diff --git a/security/FaceRecognition/README.md b/security/FaceRecognition/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..264cd26028e5524d260dae92689c699b53f84723
--- /dev/null
+++ b/security/FaceRecognition/README.md
@@ -0,0 +1,3 @@
+# Facial Recognition
+
+- Currently, 2D and 3D facial recognition are supported and can be used in identity authentication scenarios such as device unlocking, application login, and payment.
\ No newline at end of file
diff --git a/security/FaceRecognition/README_zh.md b/security/FaceRecognition/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..268953f55ed03fa37d03bd2a4e7cc66da2db2419
--- /dev/null
+++ b/security/FaceRecognition/README_zh.md
@@ -0,0 +1,3 @@
+# 人脸识别
+
+- 当前生物特征识别支持2D人脸识别、3D人脸识别,可应用于设备解锁、应用登录、支付等身份认证场景。
\ No newline at end of file
diff --git a/security/FaceRecognition/build.gradle b/security/FaceRecognition/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..e76a14f743baa5377849b43abf29dd0fe29b6478
--- /dev/null
+++ b/security/FaceRecognition/build.gradle
@@ -0,0 +1,34 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+buildscript {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ }
+}
+allprojects {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
\ No newline at end of file
diff --git a/security/FaceRecognition/entry/build.gradle b/security/FaceRecognition/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..1324a93eda46cb945cc94de68b1cb0d1bcca10d1
--- /dev/null
+++ b/security/FaceRecognition/entry/build.gradle
@@ -0,0 +1,18 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+}
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+}
diff --git a/security/FaceRecognition/entry/src/main/config.json b/security/FaceRecognition/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..945fb5632a680582d7ba65d2f01dd3579d99fc28
--- /dev/null
+++ b/security/FaceRecognition/entry/src/main/config.json
@@ -0,0 +1,53 @@
+{
+ "app": {
+ "bundleName": "ohos.samples.facerecognition",
+ "version": {
+ "code": 1000000,
+ "name": "1.0"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "ohos.samples.facerecognition",
+ "name": ".MainAbility",
+ "reqCapabilities": [
+ "video_support"
+ ],
+ "deviceType": [
+ "default"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry",
+ "installationFree":false
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "portrait",
+ "formsEnabled": false,
+ "name": ".MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ],
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.ACCESS_BIOMETRIC"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/security/FaceRecognition/entry/src/main/java/ohos/samples/facerecognition/MainAbility.java b/security/FaceRecognition/entry/src/main/java/ohos/samples/facerecognition/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..609c187f2c687179e28e29b2cfadb7fc47f0204e
--- /dev/null
+++ b/security/FaceRecognition/entry/src/main/java/ohos/samples/facerecognition/MainAbility.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021 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.
+ */
+
+package ohos.samples.facerecognition;
+
+import ohos.samples.facerecognition.slice.MainAbilitySlice;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+/**
+ * Facerecognition MainAbility
+ */
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/security/FaceRecognition/entry/src/main/java/ohos/samples/facerecognition/slice/MainAbilitySlice.java b/security/FaceRecognition/entry/src/main/java/ohos/samples/facerecognition/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ee321e055c00f9f5f59fcd682a79b45df7afbfb
--- /dev/null
+++ b/security/FaceRecognition/entry/src/main/java/ohos/samples/facerecognition/slice/MainAbilitySlice.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2021 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.
+ */
+
+package ohos.samples.facerecognition.slice;
+
+import ohos.samples.facerecognition.ResourceTable;
+import ohos.samples.facerecognition.utils.ThreadPoolUtil;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.Text;
+import ohos.agp.window.dialog.CommonDialog;
+import ohos.biometrics.authentication.BiometricAuthentication;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import ohos.eventhandler.InnerEvent;
+
+/**
+ * MainAbilitySlice
+ */
+public class MainAbilitySlice extends AbilitySlice {
+ private static final int EVENT_MESSAGE_SUCCESS = 0x1000001;
+
+ private static final int EVENT_MESSAGE_FAIL = 0x1000002;
+
+ private static final int BA_CHECK_NOT_ENROLLED = 4;
+
+ private Text resultText;
+
+ private String result;
+
+ private EventHandler handler = new EventHandler(EventRunner.current()) {
+ @Override
+ protected void processEvent(InnerEvent event) {
+ switch (event.eventId) {
+ case EVENT_MESSAGE_SUCCESS:
+ showDialog(result);
+ resultText.setText(result);
+ break;
+ case EVENT_MESSAGE_FAIL:
+ resultText.setText(result);
+ break;
+ }
+ }
+ };
+
+ private BiometricAuthentication biometricAuthentication;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_main_ability_slice);
+ initComponents();
+ }
+
+ private void initComponents() {
+ resultText = (Text) findComponentById(ResourceTable.Id_result_text);
+ Component startButton = findComponentById(ResourceTable.Id_start);
+ Component cancelButton = findComponentById(ResourceTable.Id_cancel);
+ startButton.setClickedListener(this::startFaceUnlock);
+ cancelButton.setClickedListener(this::cancelRecognition);
+ }
+
+ private synchronized void startFaceUnlock(Component component) {
+ try {
+ biometricAuthentication = BiometricAuthentication.getInstance(getAbility());
+ int availability = biometricAuthentication.checkAuthenticationAvailability(
+ BiometricAuthentication.AuthType.AUTH_TYPE_BIOMETRIC_FACE_ONLY,
+ BiometricAuthentication.SecureLevel.SECURE_LEVEL_S2, true);
+ if (availability == 0) {
+ execAuthentication();
+ } else if (availability == BA_CHECK_NOT_ENROLLED) {
+ result = "Face Unlock not enrolled, set up face Recognition first";
+ } else {
+ result = "Biometric authentication not support";
+ }
+
+ } catch (IllegalAccessException e) {
+ result = "Face Recognition error ";
+ }
+ handler.sendEvent(EVENT_MESSAGE_FAIL);
+ }
+
+ private void execAuthentication() {
+ ThreadPoolUtil.submit(() -> {
+ int authenticationAction = biometricAuthentication.execAuthenticationAction(
+ BiometricAuthentication.AuthType.AUTH_TYPE_BIOMETRIC_FACE_ONLY,
+ BiometricAuthentication.SecureLevel.SECURE_LEVEL_S4, true, false, null);
+ if (authenticationAction == 0) {
+ result = "Unlocked successfully";
+ handler.sendEvent(EVENT_MESSAGE_SUCCESS);
+ } else {
+ result = "Authentication failed, face biometric doesn't match";
+ handler.sendEvent(EVENT_MESSAGE_FAIL);
+ }
+ });
+ }
+
+ private void cancelRecognition(Component component) {
+ if (biometricAuthentication != null) {
+ biometricAuthentication.cancelAuthenticationAction();
+ }
+ }
+
+ private void showDialog(String message) {
+ Component container = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_dialog_layout, null, false);
+ Text content = (Text) container.findComponentById(ResourceTable.Id_message);
+ content.setText("Recognition result:" + System.lineSeparator() + message);
+ CommonDialog commonDialog = new CommonDialog(this);
+ commonDialog.setSize(900, 400);
+ commonDialog.setCornerRadius(30);
+ commonDialog.setContentCustomComponent(container);
+ commonDialog.show();
+ Component btnOk = container.findComponentById(ResourceTable.Id_btn_ok);
+ btnOk.setClickedListener(component -> commonDialog.hide());
+ }
+}
diff --git a/security/FaceRecognition/entry/src/main/java/ohos/samples/facerecognition/utils/ThreadPoolUtil.java b/security/FaceRecognition/entry/src/main/java/ohos/samples/facerecognition/utils/ThreadPoolUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..55b2df2140d090a3c41804dcd7231f715277bff6
--- /dev/null
+++ b/security/FaceRecognition/entry/src/main/java/ohos/samples/facerecognition/utils/ThreadPoolUtil.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2021 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.
+ */
+
+package ohos.samples.facerecognition.utils;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Global thread pool
+ */
+public class ThreadPoolUtil {
+ private static final int CORE_COUNT = 10;
+
+ private static final int THREAD_COUNT = 20;
+
+ private static final int WORK_QUEUE_SIZE = 50;
+
+ private static final long KEEP_ALIVE = 10L;
+
+ private static final AtomicInteger THREAD_ID = new AtomicInteger(1);
+
+ private static ThreadPoolExecutor executor = new ThreadPoolExecutor(CORE_COUNT, THREAD_COUNT, KEEP_ALIVE,
+ TimeUnit.SECONDS, new ArrayBlockingQueue<>(WORK_QUEUE_SIZE), new CommonThreadFactory());
+
+ private ThreadPoolUtil() {
+ }
+
+ /**
+ * Submit task to execute
+ *
+ * @param task runnable task
+ */
+ public static void submit(Runnable task) {
+ executor.submit(task);
+ }
+
+ /**
+ * ThreadFactory
+ *
+ */
+ static class CommonThreadFactory implements ThreadFactory {
+ @Override
+ public Thread newThread(Runnable runnable) {
+ String threadName = null;
+ if (THREAD_ID.get() == Integer.MAX_VALUE) {
+ threadName = "threadpool-common-" + THREAD_ID.getAndSet(1);
+ } else {
+ threadName = "threadpool-common-" + THREAD_ID.incrementAndGet();
+ }
+ return new Thread(runnable, threadName);
+ }
+ }
+}
diff --git a/security/FaceRecognition/entry/src/main/resources/base/element/string.json b/security/FaceRecognition/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..5616ce7d89844021b477c615b03f297c7306b441
--- /dev/null
+++ b/security/FaceRecognition/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "FaceRecognition"
+ },
+ {
+ "name": "mainability_description",
+ "value": "hap sample empty page"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/security/FaceRecognition/entry/src/main/resources/base/graphic/button_bg.xml b/security/FaceRecognition/entry/src/main/resources/base/graphic/button_bg.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f4a98035344fc8f1a3211c66ec8098eb24fdaf66
--- /dev/null
+++ b/security/FaceRecognition/entry/src/main/resources/base/graphic/button_bg.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/security/FaceRecognition/entry/src/main/resources/base/layout/dialog_layout.xml b/security/FaceRecognition/entry/src/main/resources/base/layout/dialog_layout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..92119f692a0cad4da3154205861d828d5e536084
--- /dev/null
+++ b/security/FaceRecognition/entry/src/main/resources/base/layout/dialog_layout.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/security/FaceRecognition/entry/src/main/resources/base/layout/main_ability_slice.xml b/security/FaceRecognition/entry/src/main/resources/base/layout/main_ability_slice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e7b02ad003726c5b59233ca7f79526c07be152f4
--- /dev/null
+++ b/security/FaceRecognition/entry/src/main/resources/base/layout/main_ability_slice.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/security/FaceRecognition/entry/src/main/resources/base/media/icon.png b/security/FaceRecognition/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/security/FaceRecognition/entry/src/main/resources/base/media/icon.png differ
diff --git a/security/FaceRecognition/screenshots/phone/fail.png b/security/FaceRecognition/screenshots/phone/fail.png
new file mode 100644
index 0000000000000000000000000000000000000000..a68426abee4d0e007e1a8d618405ae29371fbf8a
Binary files /dev/null and b/security/FaceRecognition/screenshots/phone/fail.png differ
diff --git a/security/FaceRecognition/screenshots/phone/main.png b/security/FaceRecognition/screenshots/phone/main.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7445116028d56b2a9214b4db5a386a08d2512df
Binary files /dev/null and b/security/FaceRecognition/screenshots/phone/main.png differ
diff --git a/security/FaceRecognition/screenshots/phone/success.png b/security/FaceRecognition/screenshots/phone/success.png
new file mode 100644
index 0000000000000000000000000000000000000000..0291f4e6c76e1a369039877c772ccdb427b5dc42
Binary files /dev/null and b/security/FaceRecognition/screenshots/phone/success.png differ
diff --git a/security/FaceRecognition/settings.gradle b/security/FaceRecognition/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07
--- /dev/null
+++ b/security/FaceRecognition/settings.gradle
@@ -0,0 +1 @@
+include ':entry'