Commit 9620a846 by Chokmongkhon Jansanom

fix: java import.

parents
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
build/
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "abb292a07e20d696c4568099f918f6c5f330e6b0"
channel: "stable"
project_type: plugin
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
- platform: android
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
- platform: ios
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
{
"java.configuration.updateBuildConfiguration": "interactive"
}
\ No newline at end of file
## 0.0.1
* First release. No code in this version.
New BSD License
Copyright 2024 Chokmongkhon Jansanom
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
# myhr_facescan
Connect luxand made easy.
## Getting Started
This project is a starting point for a Flutter
[plug-in package](https://flutter.dev/developing-packages/),
a specialized package that includes platform-specific implementation code for
Android and/or iOS.
For help getting started with Flutter development, view the
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.cxx
group 'myhr.facescan.myhr_facescan'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
if (project.android.hasProperty("namespace")) {
namespace 'myhr.facescan.myhr_facescan'
}
compileSdk 34
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
test.java.srcDirs += 'src/test/kotlin'
}
defaultConfig {
minSdkVersion 21
}
dependencies {
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation 'org.mockito:mockito-core:5.0.0'
}
testOptions {
unitTests.all {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}
\ No newline at end of file
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# 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
#
# https://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.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
rootProject.name = 'myhr_facescan'
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="myhr.facescan.myhr_facescan">
</manifest>
/*
* FaceSDK Library Interface
* Copyright (C) 2020 Luxand, Inc.
*/
package com.luxand;
public class FSDK
{
static {
//System.loadLibrary("stlport_shared");
System.loadLibrary("fsdk");
}
// Error codes
public static final int FSDKE_OK = 0;
public static final int FSDKE_FAILED = -1;
public static final int FSDKE_NOT_ACTIVATED = -2;
public static final int FSDKE_OUT_OF_MEMORY = -3;
public static final int FSDKE_INVALID_ARGUMENT = -4;
public static final int FSDKE_IO_ERROR = -5;
public static final int FSDKE_IMAGE_TOO_SMALL = -6;
public static final int FSDKE_FACE_NOT_FOUND = -7;
public static final int FSDKE_INSUFFICIENT_BUFFER_SIZE = -8;
public static final int FSDKE_UNSUPPORTED_IMAGE_EXTENSION = -9;
public static final int FSDKE_CANNOT_OPEN_FILE = -10;
public static final int FSDKE_CANNOT_CREATE_FILE = -11;
public static final int FSDKE_BAD_FILE_FORMAT = -12;
public static final int FSDKE_FILE_NOT_FOUND = -13;
public static final int FSDKE_CONNECTION_CLOSED = -14;
public static final int FSDKE_CONNECTION_FAILED = -15;
public static final int FSDKE_IP_INIT_FAILED = -16;
public static final int FSDKE_NEED_SERVER_ACTIVATION = -17;
public static final int FSDKE_ID_NOT_FOUND = -18;
public static final int FSDKE_ATTRIBUTE_NOT_DETECTED = -19;
public static final int FSDKE_INSUFFICIENT_TRACKER_MEMORY_LIMIT = -20;
public static final int FSDKE_UNKNOWN_ATTRIBUTE = -21;
public static final int FSDKE_UNSUPPORTED_FILE_VERSION = -22;
public static final int FSDKE_SYNTAX_ERROR = -23;
public static final int FSDKE_PARAMETER_NOT_FOUND = -24;
public static final int FSDKE_INVALID_TEMPLATE = -25;
public static final int FSDKE_UNSUPPORTED_TEMPLATE_VERSION = -26;
public static final int FSDKE_CAMERA_INDEX_DOES_NOT_EXIST = -27;
public static final int FSDKE_PLATFORM_NOT_LICENSED = -28;
// Facial feature count
public static final int FSDK_FACIAL_FEATURE_COUNT = 70;
// Types
public static class FSDK_VIDEOCOMPRESSIONTYPE {
public static final int FSDK_MJPEG = 0;
public int type;
}
public static class FSDK_IMAGEMODE {
public static final int FSDK_IMAGE_GRAYSCALE_8BIT = 0;
public static final int FSDK_IMAGE_COLOR_24BIT = 1;
public static final int FSDK_IMAGE_COLOR_32BIT = 2;
public int mode;
}
public static class HImage { //to pass himage "by reference"
protected int himage;
}
public static class HCamera { //to pass hcamera "by reference"
protected int hcamera;
}
public static class HTracker {
protected int htracker;
}
public static class TFacePosition {
public int xc, yc, w;
public int padding;
public double angle;
}
public static class TFaces {
public TFacePosition faces[];
public int maxFaces;
public TFaces(){
maxFaces = 100;
faces = null;
}
public TFaces(int MaxFaces){
maxFaces = MaxFaces;
faces = null;
}
}
public static class TPoint {
public int x, y;
}
public static class FSDK_Features {
public TPoint features[] = new TPoint[FSDK_FACIAL_FEATURE_COUNT];
}
public static class FSDK_FaceTemplate {
public byte template[] = new byte[1040];
}
// Facial features
public static final int FSDKP_LEFT_EYE = 0;
public static final int FSDKP_RIGHT_EYE = 1;
public static final int FSDKP_LEFT_EYE_INNER_CORNER = 24;
public static final int FSDKP_LEFT_EYE_OUTER_CORNER = 23;
public static final int FSDKP_LEFT_EYE_LOWER_LINE1 = 38;
public static final int FSDKP_LEFT_EYE_LOWER_LINE2 = 27;
public static final int FSDKP_LEFT_EYE_LOWER_LINE3 = 37;
public static final int FSDKP_LEFT_EYE_UPPER_LINE1 = 35;
public static final int FSDKP_LEFT_EYE_UPPER_LINE2 = 28;
public static final int FSDKP_LEFT_EYE_UPPER_LINE3 = 36;
public static final int FSDKP_LEFT_EYE_LEFT_IRIS_CORNER = 29;
public static final int FSDKP_LEFT_EYE_RIGHT_IRIS_CORNER = 30;
public static final int FSDKP_RIGHT_EYE_INNER_CORNER = 25;
public static final int FSDKP_RIGHT_EYE_OUTER_CORNER = 26;
public static final int FSDKP_RIGHT_EYE_LOWER_LINE1 = 41;
public static final int FSDKP_RIGHT_EYE_LOWER_LINE2 = 31;
public static final int FSDKP_RIGHT_EYE_LOWER_LINE3 = 42;
public static final int FSDKP_RIGHT_EYE_UPPER_LINE1 = 40;
public static final int FSDKP_RIGHT_EYE_UPPER_LINE2 = 32;
public static final int FSDKP_RIGHT_EYE_UPPER_LINE3 = 39;
public static final int FSDKP_RIGHT_EYE_LEFT_IRIS_CORNER = 33;
public static final int FSDKP_RIGHT_EYE_RIGHT_IRIS_CORNER = 34;
public static final int FSDKP_LEFT_EYEBROW_INNER_CORNER = 13;
public static final int FSDKP_LEFT_EYEBROW_MIDDLE = 16;
public static final int FSDKP_LEFT_EYEBROW_MIDDLE_LEFT = 18;
public static final int FSDKP_LEFT_EYEBROW_MIDDLE_RIGHT = 19;
public static final int FSDKP_LEFT_EYEBROW_OUTER_CORNER = 12;
public static final int FSDKP_RIGHT_EYEBROW_INNER_CORNER = 14;
public static final int FSDKP_RIGHT_EYEBROW_MIDDLE = 17;
public static final int FSDKP_RIGHT_EYEBROW_MIDDLE_LEFT = 20;
public static final int FSDKP_RIGHT_EYEBROW_MIDDLE_RIGHT = 21;
public static final int FSDKP_RIGHT_EYEBROW_OUTER_CORNER = 15;
public static final int FSDKP_NOSE_TIP = 2;
public static final int FSDKP_NOSE_BOTTOM = 49;
public static final int FSDKP_NOSE_BRIDGE = 22;
public static final int FSDKP_NOSE_LEFT_WING = 43;
public static final int FSDKP_NOSE_LEFT_WING_OUTER = 45;
public static final int FSDKP_NOSE_LEFT_WING_LOWER = 47;
public static final int FSDKP_NOSE_RIGHT_WING = 44;
public static final int FSDKP_NOSE_RIGHT_WING_OUTER = 46;
public static final int FSDKP_NOSE_RIGHT_WING_LOWER = 48;
public static final int FSDKP_MOUTH_RIGHT_CORNER = 3;
public static final int FSDKP_MOUTH_LEFT_CORNER = 4;
public static final int FSDKP_MOUTH_TOP = 54;
public static final int FSDKP_MOUTH_TOP_INNER = 61;
public static final int FSDKP_MOUTH_BOTTOM = 55;
public static final int FSDKP_MOUTH_BOTTOM_INNER = 64;
public static final int FSDKP_MOUTH_LEFT_TOP = 56;
public static final int FSDKP_MOUTH_LEFT_TOP_INNER = 60;
public static final int FSDKP_MOUTH_RIGHT_TOP = 57;
public static final int FSDKP_MOUTH_RIGHT_TOP_INNER = 62;
public static final int FSDKP_MOUTH_LEFT_BOTTOM = 58;
public static final int FSDKP_MOUTH_LEFT_BOTTOM_INNER = 63;
public static final int FSDKP_MOUTH_RIGHT_BOTTOM = 59;
public static final int FSDKP_MOUTH_RIGHT_BOTTOM_INNER = 65;
public static final int FSDKP_NASOLABIAL_FOLD_LEFT_UPPER = 50;
public static final int FSDKP_NASOLABIAL_FOLD_LEFT_LOWER = 52;
public static final int FSDKP_NASOLABIAL_FOLD_RIGHT_UPPER = 51;
public static final int FSDKP_NASOLABIAL_FOLD_RIGHT_LOWER = 53;
public static final int FSDKP_CHIN_BOTTOM = 11;
public static final int FSDKP_CHIN_LEFT = 9;
public static final int FSDKP_CHIN_RIGHT = 10;
public static final int FSDKP_FACE_CONTOUR1 = 7;
public static final int FSDKP_FACE_CONTOUR2 = 5;
public static final int FSDKP_FACE_CONTOUR12 = 6;
public static final int FSDKP_FACE_CONTOUR13 = 8;
public static final int FSDKP_FACE_CONTOUR14 = 66;
public static final int FSDKP_FACE_CONTOUR15 = 67;
public static final int FSDKP_FACE_CONTOUR16 = 68;
public static final int FSDKP_FACE_CONTOUR17 = 69;
public static native int ActivateLibrary(String LicenseKey);
//public static native int GetHardware_ID(String HardwareID[]); //not implemented
public static native int GetLicenseInfo(String LicenseInfo[]);
public static native int SetNumThreads(int Num);
public static native int GetNumThreads(int Num[]);
public static native int Initialize();
public static native int Finalize();
public static native int CreateEmptyImage(HImage Image);
public static native int FreeImage(HImage Image);
public static native int LoadImageFromFile(HImage Image, String FileName);
public static native int LoadImageFromFileWithAlpha(HImage Image, String FileName);
public static native int SaveImageToFile(HImage Image, String FileName);
public static native int SetJpegCompressionQuality(int Quality);
public static native int GetImageWidth(HImage Image, int Width[]);
public static native int GetImageHeight(HImage Image, int Height[]);
public static native int LoadImageFromBuffer(HImage Image, byte Buffer[], int Width, int Height, int ScanLine, FSDK_IMAGEMODE ImageMode);
public static native int GetImageBufferSize(HImage Image, int BufSize [], FSDK_IMAGEMODE ImageMode);
public static native int SaveImageToBuffer(HImage Image, byte Buffer[], FSDK_IMAGEMODE ImageMode);
public static native int LoadImageFromJpegBuffer(HImage Image, byte Buffer[], int BufferLength);
public static native int LoadImageFromPngBuffer(HImage Image, byte Buffer[], int BufferLength);
public static native int LoadImageFromPngBufferWithAlpha(HImage Image, byte Buffer[], int BufferLength);
public static native int DetectFace(HImage Image, TFacePosition FacePosition);
public static native int DetectMultipleFaces(HImage Image, TFaces FacePositions);
public static native int SetFaceDetectionParameters(boolean HandleArbitraryRotations, boolean DetermineFaceRotationAngle, int InternalResizeWidth);
public static native int SetFaceDetectionThreshold(int Threshold);
public static native int GetDetectedFaceConfidence(int Confidence[]);
public static native int DetectFacialFeatures(HImage Image, FSDK_Features FacialFeatures);
public static native int DetectFacialFeaturesInRegion(HImage Image, TFacePosition FacePosition, FSDK_Features FacialFeatures);
public static native int DetectEyes(HImage Image, FSDK_Features Eyes);
public static native int DetectEyesInRegion(HImage Image, TFacePosition FacePosition, FSDK_Features Eyes);
public static native int CopyImage(HImage SourceImage, HImage DestImage);
public static native int ResizeImage(HImage SourceImage, double ratio, HImage DestImage);
public static native int RotateImage90(HImage SourceImage, int Multiplier, HImage DestImage);
public static native int RotateImage(HImage SourceImage, double angle, HImage DestImage);
public static native int RotateImageCenter(HImage SourceImage, double angle, double xCenter, double yCenter, HImage DestImage);
public static native int CopyRect(HImage SourceImage, int x1, int y1, int x2, int y2, HImage DestImage);
public static native int CopyRectReplicateBorder(HImage SourceImage, int x1, int y1, int x2, int y2, HImage DestImage);
public static native int MirrorImage(HImage Image, boolean UseVerticalMirroringInsteadOfHorizontal);
public static native int ExtractFaceImage(HImage Image, FSDK_Features FacialFeatures, int Width, int Height, HImage ExtractedFaceImage, FSDK_Features ResizedFeatures);
public static native int GetFaceTemplate(HImage Image, FSDK_FaceTemplate FaceTemplate);
public static native int GetFaceTemplateInRegion(HImage Image, TFacePosition FacePosition, FSDK_FaceTemplate FaceTemplate);
public static native int GetFaceTemplateUsingFeatures(HImage Image, FSDK_Features FacialFeatures, FSDK_FaceTemplate FaceTemplate);
public static native int GetFaceTemplateUsingEyes(HImage Image, FSDK_Features EyeCoords, FSDK_FaceTemplate FaceTemplate);
public static native int MatchFaces(FSDK_FaceTemplate FaceTemplate1, FSDK_FaceTemplate FaceTemplate2, float Similarity[]);
public static native int GetMatchingThresholdAtFAR(float FARValue, float Threshold[]);
public static native int GetMatchingThresholdAtFRR(float FRRValue, float Threshold[]);
public static native int CreateTracker(HTracker Tracker);
public static native int FreeTracker(HTracker Tracker);
public static native int ClearTracker(HTracker Tracker);
public static native int SetTrackerParameter(HTracker Tracker, String ParameterName, String ParameterValue);
public static native int SetTrackerMultipleParameters(HTracker Tracker, String Parameters, int ErrorPosition[]);
public static native int GetTrackerParameter(HTracker Tracker, String ParameterName, String ParameterValue[], int MaxSizeInBytes);
public static native int FeedFrame(HTracker Tracker, long CameraIdx, HImage Image, long FaceCount[], long IDs[]);
public static native int GetTrackerEyes(HTracker Tracker, long CameraIdx, long ID, FSDK_Features Eyes);
public static native int GetTrackerFacialFeatures(HTracker Tracker, long CameraIdx, long ID, FSDK_Features FacialFeatures);
public static native int GetTrackerFacePosition(HTracker Tracker, long CameraIdx, long ID, TFacePosition FacePosition);
public static native int LockID(HTracker Tracker, long ID);
public static native int UnlockID(HTracker Tracker, long ID);
public static native int PurgeID(HTracker Tracker, long ID);
public static native int SetName(HTracker Tracker, long ID, String Name);
public static native int GetName(HTracker Tracker, long ID, String Name[], long MaxSizeInBytes);
public static native int GetAllNames(HTracker Tracker, long ID, String Names[], long MaxSizeInBytes);
public static native int GetIDReassignment(HTracker Tracker, long ID, long ReassignedID[]);
public static native int GetSimilarIDCount(HTracker Tracker, long ID, long Count[]);
public static native int GetSimilarIDList(HTracker Tracker, long ID, long SimilarIDList[]);
public static native int SaveTrackerMemoryToFile(HTracker Tracker, String FileName);
public static native int LoadTrackerMemoryFromFile(HTracker Tracker, String FileName);
public static native int GetTrackerMemoryBufferSize(HTracker Tracker, long [] BufSize);
public static native int SaveTrackerMemoryToBuffer(HTracker Tracker, byte Buffer[]);
public static native int LoadTrackerMemoryFromBuffer(HTracker Tracker, byte Buffer[]);
public static native int GetTrackerFacialAttribute(HTracker Tracker, long CameraIdx, long ID, String AttributeName, String AttributeValues[], long MaxSizeInBytes);
public static native int DetectFacialAttributeUsingFeatures(HImage Image, FSDK_Features FacialFeatures, String AttributeName, String AttributeValues[], long MaxSizeInBytes);
public static native int GetValueConfidence(String AttributeValues, String Value, float Confidence[]);
public static native int SetHTTPProxy(String ServerNameOrIPAddress, short Port, String UserName, String Password);
public static native int OpenIPVideoCamera(FSDK_VIDEOCOMPRESSIONTYPE CompressionType, String URL, String Username, String Password, int TimeoutSeconds, HCamera CameraHandle);
public static native int CloseVideoCamera(HCamera CameraHandle);
public static native int GrabFrame(HCamera CameraHandle, HImage Image);
public static native int InitializeCapturing();
public static native int FinalizeCapturing();
public static native int SetParameter(String ParameterName, String ParameterValue);
public static native int SetParameters(String Parameters, int ErrorPosition[]);
}
package myhr.facescan.myhr_facescan;
import android.util.Log;
import com.luxand.FSDK;
import com.luxand.FSDK.HImage;
public class LuxandSdk {
static FSDK.HTracker tracker;
static final int CAMERA_ID = 0;
static boolean isTrackingMode = false;
static LowPassFilter pan = new LowPassFilter();
static LowPassFilter tilt = new LowPassFilter();
public static int Initialize(String licenseKey) {
int libCode = FSDK.ActivateLibrary(licenseKey);
if (libCode == FSDK.FSDKE_OK) {
libCode = FSDK.Initialize();
}
return libCode;
}
public static int SetTrackingMode() {
int[] err_pos = new int[1];
int libCode = FSDK.SetTrackerMultipleParameters(tracker,
"RecognizeFaces=false;" +
"DetectFacialFeatures=true;" +
"HandleArbitraryRotations=true;" +
"DetermineFaceRotationAngle=true;" +
"InternalResizeWidth=100;" +
"FaceDetectionThreshold=5;" +
"DetectGender=true;" +
"DetectAge=true;" +
"DetectExpression=true;" +
"DetectAngles=true;", err_pos);
if (err_pos[0] != 0) {
Log.i("Failed to SetTrackerMultipleParameters: ", String.valueOf(err_pos[0]));
}
return libCode;
// return FSDK.SetFaceDetectionParameters(false, false, 100);
}
public static int SetDetectionMode() {
int[] err_pos = new int[1];
int libCode = FSDK.SetTrackerMultipleParameters(tracker,
"RecognizeFaces=false;" +
"DetectFacialFeatures=true;" +
"HandleArbitraryRotations=false;" +
"DetermineFaceRotationAngle=false;" +
"InternalResizeWidth=500;" +
"FaceDetectionThreshold=5;" +
"DetectGender=false;" +
"DetectAge=false;" +
"DetectExpression=false;" +
"DetectAngles=false;", err_pos);
if (err_pos[0] != 0) {
Log.i("Failed to SetTrackerMultipleParameters: ", String.valueOf(err_pos[0]));
}
return libCode;
// return FSDK.SetFaceDetectionParameters(true, false, 500);
}
private static void ValidateTracker() {
if (isTrackingMode) {
return;
}
tracker = new FSDK.HTracker();
if (FSDK.CreateTracker(tracker) == FSDK.FSDKE_OK) {
isTrackingMode = true;
SetTrackingMode();
}
}
private static void ValidateDetector() {
if (!isTrackingMode) {
return;
}
if (FreeTracker() == FSDK.FSDKE_OK) {
SetDetectionMode();
}
}
public static int FreeTracker() {
int libCode = FSDK.FreeTracker(tracker);
if (libCode == FSDK.FSDKE_OK) {
tracker = null;
isTrackingMode = false;
}
return libCode;
}
public static int[] TrackFace(byte[] buffer) {
ValidateTracker();
int[] result = new int[5];
HImage image = new HImage();
int libCode = FSDK.LoadImageFromJpegBuffer(image, buffer, buffer.length);
if (libCode != FSDK.FSDKE_OK) {
Log.i("Failed to load image: ", String.valueOf(libCode));
return result;
}
long[] faceCount = new long[5];
long[] ids = new long[5];
libCode = FSDK.FeedFrame(tracker, CAMERA_ID, image, faceCount, ids);
FSDK.FreeImage(image);
if (libCode != FSDK.FSDKE_OK) {
Log.i("Failed to feed frame: ", String.valueOf(libCode));
return result;
}
FSDK.TFacePosition pos = new FSDK.TFacePosition();
libCode = FSDK.GetTrackerFacePosition(tracker, CAMERA_ID, ids[0], pos);
if (libCode != FSDK.FSDKE_OK) {
//Log.i("Failed to get tracker position: ", String.valueOf(libCode));
return result;
}
result[0] = pos.xc;
result[1] = pos.yc;
result[2] = pos.w;
String sAttr[] = new String[]{""};
libCode = FSDK.GetTrackerFacialAttribute(tracker, 0, ids[0], "Age", sAttr, 256);
if (libCode == FSDK.FSDKE_OK) {
result[3] = (byte) Math.round(Double.parseDouble(sAttr[0].split(";")[0].split("=")[1]));
} else {
Log.i("Failed to GetTrackerFacialAttribute Age: ", String.valueOf(libCode));
}
libCode = FSDK.GetTrackerFacialAttribute(tracker, 0, ids[0], "Gender", sAttr, 256);
if (libCode == FSDK.FSDKE_OK) {
result[4] = Double.parseDouble(sAttr[0].split(";")[0].split("=")[1]) > 0.8 ? 1 : 2;
} else {
Log.i("Failed to GetTrackerFacialAttribute Gender: ", String.valueOf(libCode));
}
return result;
}
public static double[] GetFaceAttribute(byte[] buffer, Boolean isExpression) {
ValidateTracker();
double[] result = new double[2];
HImage image = new HImage();
int libCode = FSDK.LoadImageFromJpegBuffer(image, buffer, buffer.length);
if (libCode != FSDK.FSDKE_OK) {
Log.i("Failed to load image: ", String.valueOf(libCode));
return result;
}
long[] faceCount = new long[5];
long[] ids = new long[5];
libCode = FSDK.FeedFrame(tracker, CAMERA_ID, image, faceCount, ids);
FSDK.FreeImage(image);
if (libCode != FSDK.FSDKE_OK) {
Log.i("Failed to feed frame: ", String.valueOf(libCode));
return result;
}
String sAttr[] = new String[]{""};
libCode = FSDK.GetTrackerFacialAttribute(tracker, 0, ids[0], isExpression ? "Expression" : "Angles", sAttr, 256);
if (libCode != FSDK.FSDKE_OK) {
Log.i("Failed to GetTrackerFacialAttribute: ", String.valueOf(libCode));
return result;
}
Log.i("============================== GetTrackerFacialAttribute: ", sAttr[0]);
String attr[] = sAttr[0].split(";");
// Expression - 0 is Smile, 1 is EyesOpen
// Angles - 0 is Pan, 1 is Tilt
if (isExpression) {
result[0] = Double.parseDouble(attr[0].split("=")[1]);
result[1] = Double.parseDouble(attr[1].split("=")[1]);
} else {
result[0] = pan.pass(Float.parseFloat(attr[1].split("=")[1]));
result[1] = tilt.pass(Float.parseFloat(attr[2].split("=")[1]));
}
return result;
}
public static byte[][] GetTemplate(byte[] buffer) {
ValidateDetector();
byte[][] templates = new byte[2][];
HImage image = new HImage();
int libCode = FSDK.LoadImageFromJpegBuffer(image, buffer, buffer.length);
FSDK.FreeImage(image);
if (libCode != FSDK.FSDKE_OK) {
Log.i("Failed to load image: ", String.valueOf(libCode));
return templates;
}
FSDK.FSDK_Features eyes = new FSDK.FSDK_Features();
libCode = FSDK.DetectEyes(image, eyes);
if (libCode != FSDK.FSDKE_OK) {
Log.i("Cannot detect eye: ", String.valueOf(libCode));
return templates;
}
FSDK.FSDK_FaceTemplate ft = new FSDK.FSDK_FaceTemplate();
FSDK.GetFaceTemplateUsingEyes(image, eyes, ft);
templates[0] = ft.template;
FSDK.FSDK_Features face = new FSDK.FSDK_Features();
libCode = FSDK.DetectFacialFeatures(image, face);
if (libCode != FSDK.FSDKE_OK) {
Log.i("Cannot detect face: ", String.valueOf(libCode));
return templates;
}
ft = new FSDK.FSDK_FaceTemplate();
FSDK.GetFaceTemplateUsingFeatures(image, face, ft);
templates[1] = ft.template;
return templates;
}
}
class LowPassFilter {
private float a;
private Float y = null;
public LowPassFilter() {
a = 0.325f;
}
public float pass(final float x) {
y = a * x + (1 - a) * (y == null ? x : y);
return y;
}
}
\ No newline at end of file
package myhr.facescan.myhr_facescan
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import java.io.ByteArrayOutputStream
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
/** MyhrFacescanPlugin */
class MyhrFacescanPlugin : FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel: MethodChannel
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "myhr_facescan")
channel.setMethodCallHandler(this)
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "activateLuxand") {
result.success(activateLuxand(call.arguments))
} else if (call.method == "detectFace") {
GlobalScope.launch {
val found = detectFace(call.arguments)
result.success(found)
}
} else if (call.method == "getFaceTemplate") {
val templates = getFaceTemplate(call.arguments)
var s1 = templates.get(0)?.decodeToString()
var s2 = templates.get(1)?.decodeToString()
var stringArrays = arrayListOf(s1, s2)
result.success(stringArrays)
} else if (call.method == "getFaceAttribute") {
GlobalScope.launch {
val data = getFaceAttribute(call.arguments)
result.success(data)
}
} else if (call.method == "freeResource") {
LuxandSdk.FreeTracker()
} else {
result.notImplemented()
}
}
private fun activateLuxand(data: Any): Int {
val key = data as Map<String, String>
val licenseKey = key["licenseKey"] as String
val libCode = LuxandSdk.Initialize(licenseKey);
return libCode;
}
private fun getImageBytes(data: Any): ByteArray {
val key = data as Map<String, String>
val bytesList = key["platforms"] as List<ByteArray>;
val strides = key["strides"] as IntArray;
val width = key["width"] as Int;
val height = key["height"] as Int;
val imageBytes = YuvConverter.NV21toJPEG(
YuvConverter.YUVtoNV21(
bytesList, strides, width, height
), width, height, 80
)
return imageBytes
}
private fun detectFace(data: Any): IntArray {
val imageBytes = getImageBytes(data)
val rotateBitmap = rotateImage(byteArrayToBitmap(imageBytes), 270f)
val bytes = bitmapToByteArray(rotateBitmap, Bitmap.CompressFormat.JPEG, 100)
return LuxandSdk.TrackFace(bytes)
}
private fun getFaceTemplate(data: Any): Array<ByteArray> {
val imageBytes = getImageBytes(data)
val rotateBitmap = rotateImage(byteArrayToBitmap(imageBytes), 270f)
val result = bitmapToByteArray(rotateBitmap, Bitmap.CompressFormat.JPEG, 100)
val templates = LuxandSdk.GetTemplate(result)
return templates
}
private fun getFaceAttribute(data: Any): DoubleArray {
val imageBytes = getImageBytes(data)
val rotateBitmap = rotateImage(byteArrayToBitmap(imageBytes), 270f)
val result = bitmapToByteArray(rotateBitmap, Bitmap.CompressFormat.JPEG, 100)
val key = data as Map<String, String>
val isExpression = key["isExpression"] as Boolean;
return LuxandSdk.GetFaceAttribute(result, isExpression)
}
fun bitmapToByteArray(bitmap: Bitmap, format: Bitmap.CompressFormat, quality: Int): ByteArray? {
val stream = ByteArrayOutputStream()
if (!bitmap.compress(format, quality, stream)) {
return null
}
return stream.toByteArray()
}
fun byteArrayToBitmap(byteArray: ByteArray): Bitmap {
return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
}
fun rotateImage(bitmap: Bitmap, degrees: Float): Bitmap {
val matrix = Matrix()
matrix.postRotate(degrees)
matrix.postScale(-1f, 1f, bitmap.width / 2f, bitmap.height / 2f);
val rotatedBitmap = Bitmap.createBitmap(
bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true
)
return rotatedBitmap
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
}
package myhr.facescan.myhr_facescan;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.List;
public class YuvConverter {
/**
* Converts an NV21 image into JPEG compressed.
* @param nv21 byte[] of the input image in NV21 format
* @param width Width of the image.
* @param height Height of the image.
* @param quality Quality of compressed image(0-100)
* @return byte[] of a compressed Jpeg image.
*/
public static byte[] NV21toJPEG(byte[] nv21, int width, int height, int quality) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
YuvImage yuv = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
yuv.compressToJpeg(new Rect(0, 0, width, height), quality, out);
return out.toByteArray();
}
/**
* Format YUV_420 planes in to NV21.
* Removes strides from planes and combines the result to single NV21 byte array.
* @param planes List of Bytes list
* @param strides contains the strides of each plane. The structure :
* strideRowFirstPlane,stridePixelFirstPlane, strideRowSecondPlane
* @param width Width of the image
* @param height Height of given image
* @return NV21 image byte[].
*/
public static byte[] YUVtoNV21 (List<byte[]> planes, int[] strides, int width, int height) {
Rect crop = new Rect(0, 0, width, height);
int format = ImageFormat.YUV_420_888;
byte[] data = new byte[width * height * ImageFormat.getBitsPerPixel(format) / 8];
byte[] rowData = new byte[strides[0]];
int channelOffset = 0;
int outputStride = 1;
for (int i = 0; i < planes.size(); i++) {
switch (i) {
case 0:
channelOffset = 0;
outputStride = 1;
break;
case 1:
channelOffset = width * height + 1;
outputStride = 2;
break;
case 2:
channelOffset = width * height;
outputStride = 2;
break;
}
ByteBuffer buffer = ByteBuffer.wrap(planes.get(i));
int rowStride;
int pixelStride;
if(i ==0 ) {
rowStride = strides[i];
pixelStride = strides[i+1];
}
else {
rowStride = strides[i *2 ];
pixelStride = strides[i *2 +1];
}
int shift = (i == 0) ? 0 : 1;
int w = width >> shift;
int h = height >> shift;
buffer.position(rowStride * (crop.top >> shift) + pixelStride * (crop.left >> shift));
for (int row = 0; row < h; row++) {
int length;
if (pixelStride == 1 && outputStride == 1) {
length = w;
buffer.get(data, channelOffset, length);
channelOffset += length;
} else {
length = (w - 1) * pixelStride + 1;
buffer.get(rowData, 0, length);
for (int col = 0; col < w; col++) {
data[channelOffset] = rowData[col * pixelStride];
channelOffset += outputStride;
}
}
if (row < h - 1) {
buffer.position(buffer.position() + rowStride - length);
}
}
}
return data;
}
}
package myhr.facescan.myhr_facescan
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import kotlin.test.Test
import org.mockito.Mockito
/*
* This demonstrates a simple unit test of the Kotlin portion of this plugin's implementation.
*
* Once you have built the plugin's example app, you can run these tests from the command
* line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or
* you can run them directly from IDEs that support JUnit such as Android Studio.
*/
internal class MyhrFacescanPluginTest {
@Test
fun onMethodCall_getPlatformVersion_returnsExpectedValue() {
val plugin = MyhrFacescanPlugin()
val call = MethodCall("getPlatformVersion", null)
val mockResult: MethodChannel.Result = Mockito.mock(MethodChannel.Result::class.java)
plugin.onMethodCall(call, mockResult)
Mockito.verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE)
}
}
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
# myhr_facescan_example
Demonstrates how to use the myhr_facescan plugin.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
android {
namespace "myhr.facescan.myhr_facescan_example"
compileSdk flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "myhr.facescan.myhr_facescan_example"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 28
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {}
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="myhr_facescan_example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility?hl=en and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
package myhr.facescan.myhr_facescan_example
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity()
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true
android.enableJetifier=true
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
}
include ":app"
// This is a basic Flutter integration test.
//
// Since integration tests run in a full Flutter application, they can interact
// with the host side of a plugin implementation, unlike Dart unit tests.
//
// For more information about Flutter integration tests, please see
// https://docs.flutter.dev/cookbook/testing/integration/introduction
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:myhr_facescan/myhr_facescan.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('getPlatformVersion test', (WidgetTester tester) async {
final MyhrFacescan plugin = MyhrFacescan();
final String? version = await plugin.getPlatformVersion();
// The version string depends on the host platform running the test, so
// just assert that some non-empty string is returned.
expect(version?.isNotEmpty, true);
});
}
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
</dict>
</plist>
#include "Generated.xcconfig"
#include "Generated.xcconfig"
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
);
buildRules = (
);
dependencies = (
331C8086294A63A400263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C8080294A63A400263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
331C807F294A63A400263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
331C807D294A63A400263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = myhr.facescan.myhrFacescanExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = myhr.facescan.myhrFacescanExample.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = myhr.facescan.myhrFacescanExample.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = myhr.facescan.myhrFacescanExample.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = myhr.facescan.myhrFacescanExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = myhr.facescan.myhrFacescanExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C8088294A63A400263BE5 /* Debug */,
331C8089294A63A400263BE5 /* Release */,
331C808A294A63A400263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Myhr Facescan</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>myhr_facescan_example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
#import "GeneratedPluginRegistrant.h"
import Flutter
import UIKit
import XCTest
@testable import myhr_facescan
// This demonstrates a simple unit test of the Swift portion of this plugin's implementation.
//
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
class RunnerTests: XCTestCase {
func testGetPlatformVersion() {
let plugin = MyhrFacescanPlugin()
let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: [])
let resultExpectation = expectation(description: "result block must be called.")
plugin.handle(call) { result in
XCTAssertEqual(result as! String, "iOS " + UIDevice.current.systemVersion)
resultExpectation.fulfill()
}
waitForExpectations(timeout: 1)
}
}
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:myhr_facescan/enroll/index.dart';
import 'package:myhr_facescan/myhr_facescan.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const GetMaterialApp(home: HomePage());
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Test'),
),
body: Column(
children: [
ElevatedButton(
onPressed: () => Get.to(const EnrollPage()),
child: const Text('Enroll'))
],
),
);
}
}
class EnrollPage extends StatelessWidget {
const EnrollPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Enroll Face'),
),
body: const SafeArea(
child: SingleChildScrollView(
child: EnrollFace(
licenseKey: '',
),
)),
);
}
}
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
archive:
dependency: transitive
description:
name: archive
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
url: "https://pub.dev"
source: hosted
version: "3.4.10"
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
camera:
dependency: transitive
description:
name: camera
sha256: "9499cbc2e51d8eb0beadc158b288380037618ce4e30c9acbc4fae1ac3ecb5797"
url: "https://pub.dev"
source: hosted
version: "0.10.5+9"
camera_android:
dependency: transitive
description:
name: camera_android
sha256: "351429510121d179b9aac5a2e8cb525c3cd6c39f4d709c5f72dfb21726e52371"
url: "https://pub.dev"
source: hosted
version: "0.10.8+16"
camera_avfoundation:
dependency: transitive
description:
name: camera_avfoundation
sha256: "8b113e43ee4434c9244c03c905432a0d5956cedaded3cd7381abaab89ce50297"
url: "https://pub.dev"
source: hosted
version: "0.9.14+1"
camera_platform_interface:
dependency: transitive
description:
name: camera_platform_interface
sha256: a250314a48ea337b35909a4c9d5416a208d736dcb01d0b02c6af122be66660b0
url: "https://pub.dev"
source: hosted
version: "2.7.4"
camera_web:
dependency: transitive
description:
name: camera_web
sha256: f18ccfb33b2a7c49a52ad5aa3f07330b7422faaecbdfd9b9fe8e51182f6ad67d
url: "https://pub.dev"
source: hosted
version: "0.3.2+4"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
url: "https://pub.dev"
source: hosted
version: "0.3.4+1"
crypto:
dependency: transitive
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.3"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.dev"
source: hosted
version: "1.0.6"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_driver:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
url: "https://pub.dev"
source: hosted
version: "3.0.1"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
url: "https://pub.dev"
source: hosted
version: "2.0.17"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
fuchsia_remote_debug_protocol:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
get:
dependency: "direct main"
description:
name: get
sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e
url: "https://pub.dev"
source: hosted
version: "4.6.6"
image:
dependency: transitive
description:
name: image
sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
url: "https://pub.dev"
source: hosted
version: "4.1.7"
integration_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
js:
dependency: transitive
description:
name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
url: "https://pub.dev"
source: hosted
version: "0.7.1"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
url: "https://pub.dev"
source: hosted
version: "2.0.1"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
url: "https://pub.dev"
source: hosted
version: "2.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
url: "https://pub.dev"
source: hosted
version: "3.0.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev"
source: hosted
version: "0.8.0"
meta:
dependency: transitive
description:
name: meta
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
url: "https://pub.dev"
source: hosted
version: "1.11.0"
myhr_facescan:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "0.0.2"
path:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
platform:
dependency: transitive
description:
name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
url: "https://pub.dev"
source: hosted
version: "3.7.4"
process:
dependency: transitive
description:
name: process
sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32"
url: "https://pub.dev"
source: hosted
version: "5.0.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
stream_transform:
dependency: transitive
description:
name: stream_transform
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
sync_http:
dependency: transitive
description:
name: sync_http
sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
url: "https://pub.dev"
source: hosted
version: "0.3.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
url: "https://pub.dev"
source: hosted
version: "13.0.0"
web:
dependency: transitive
description:
name: web
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
webdriver:
dependency: transitive
description:
name: webdriver
sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e"
url: "https://pub.dev"
source: hosted
version: "3.0.3"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.5.0"
sdks:
dart: ">=3.3.0 <4.0.0"
flutter: ">=3.16.6"
name: myhr_facescan_example
description: "Demonstrates how to use the myhr_facescan plugin."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
sdk: '>=3.3.0 <4.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
get:
myhr_facescan:
# When depending on this package from a real application you should use:
# myhr_facescan: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6
dev_dependencies:
integration_test:
sdk: flutter
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^3.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:myhr_facescan_example/main.dart';
void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that platform version is retrieved.
expect(
find.byWidgetPredicate(
(Widget widget) => widget is Text &&
widget.data!.startsWith('Running on:'),
),
findsOneWidget,
);
});
}
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/ephemeral/
/Flutter/flutter_export_environment.sh
\ No newline at end of file
import Flutter
import UIKit
public class MyhrFacescanPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "myhr_facescan", binaryMessenger: registrar.messenger())
let instance = MyhrFacescanPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getPlatformVersion":
result("iOS " + UIDevice.current.systemVersion)
default:
result(FlutterMethodNotImplemented)
}
}
}
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint myhr_facescan.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'myhr_facescan'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin project.'
s.description = <<-DESC
A new Flutter plugin project.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.platform = :ios, '11.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
s.swift_version = '5.0'
end
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image/image.dart' as imglib;
import 'package:myhr_facescan/enroll/template_model.dart';
import 'package:myhr_facescan/luxand_controller.dart';
import 'package:myhr_facescan/throttler.dart';
class EnrollController extends GetxController {
EnrollController({required this.licenseKey});
CameraController? camController;
final _throttler = Throttler(milliSeconds: 100);
// StreamSubscription<int> _timer = null;
final String licenseKey;
var isFoundFace = false.obs;
var faceX = 0.0.obs;
var faceY = 0.0.obs;
var faceW = 0.0.obs;
var isCameraReady = false.obs;
var faces = <Image>[].obs;
var age = 0.obs;
var isMale = true.obs;
var currentCommand = 0.obs;
var livenessMode = false.obs;
var commands = <ECommand>[];
var templates = <TemplateModel>[];
var gettingCurrentImage = false;
LuxandController? luxand;
get commandName {
switch (commands[currentCommand.value]) {
case ECommand.lookStraight:
return 'มองตรง';
case ECommand.turnLeft:
return 'หันไปทางซ้าย';
case ECommand.turnRight:
return 'หันไปทางขวา';
case ECommand.lookUp:
return 'เงยหน้า';
case ECommand.lookDown:
return 'ก้มหน้า';
case ECommand.smile:
return 'ยิ้ม';
default:
return 'N/A';
}
}
approveCommand() async {
if (currentCommand.value + 1 >= commands.length) {
currentCommand.value = 0;
} else {
currentCommand.value += 1;
}
camController!.stopImageStream();
await Future.delayed(const Duration(seconds: 3));
camController!.startImageStream(onAvailable);
}
initCamera() async {
final cameraDescription = (await availableCameras())
.where(
(element) => element.lensDirection == CameraLensDirection.front,
)
.first;
camController = CameraController(cameraDescription, ResolutionPreset.high,
enableAudio: false,
imageFormatGroup: Platform.isIOS
? ImageFormatGroup.bgra8888
: ImageFormatGroup.yuv420);
}
onAvailable(CameraImage image) async {
_throttler.run(() async {
if (livenessMode.value) {
var cm = commands[currentCommand.value];
var isExpression = cm == ECommand.smile;
var attr = await luxand!.getFaceAttribute(image, isExpression);
if (isExpression) {
// const double SMILE_CONF_LEVEL_LOW = 0.3;
const double SMILE_CONF_LEVEL_HIGH = 0.6;
if (attr[0] > SMILE_CONF_LEVEL_HIGH && cm == ECommand.smile) {
print(
'========================================== Smile attr=${attr[0]}, SMILE_CONF_LEVEL_HIGH=$SMILE_CONF_LEVEL_HIGH');
await approveCommand();
}
} else {
if (cm == ECommand.turnLeft ||
cm == ECommand.turnRight ||
cm == ECommand.lookStraight) {
const double HOR_CONF_LEVEL_LOW = 2;
const double HOR_CONF_LEVEL_HIGH = 17;
if (attr[0].abs() > HOR_CONF_LEVEL_HIGH) {
if (attr[0] > 0 && cm == ECommand.turnLeft) {
print(
'========================================== Turn Left attr=${attr[0]}, HOR_CONF_LEVEL_HIGH=$HOR_CONF_LEVEL_HIGH');
await approveCommand();
} else if (attr[0] <= 0 && cm == ECommand.turnRight) {
print(
'========================================== Turn Right attr=${attr[0]}, HOR_CONF_LEVEL_HIGH=$HOR_CONF_LEVEL_HIGH');
await approveCommand();
}
} else if (attr[0].abs() < HOR_CONF_LEVEL_LOW &&
cm == ECommand.lookStraight) {
print(
'========================================== Look Straight attr=${attr[0]}, HOR_CONF_LEVEL_LOW=$HOR_CONF_LEVEL_LOW');
await approveCommand();
}
} else {
// const double UP_CONF_LEVEL_LOW = 2;
const double UP_CONF_LEVEL_HIGH = 6;
// const double DOWN_CONF_LEVEL_LOW = -2;
const double DOWN_CONF_LEVEL_HIGH = -3;
if (attr[1] > UP_CONF_LEVEL_HIGH && cm == ECommand.lookUp) {
print(
'========================================== Look Up attr=${attr[1]}, UP_CONF_LEVEL_HIGH=$UP_CONF_LEVEL_HIGH');
await approveCommand();
} else if (attr[1] < DOWN_CONF_LEVEL_HIGH &&
cm == ECommand.lookDown) {
print(
'========================================== Look Down attr=${attr[1]}, DOWN_CONF_LEVEL_HIGH=$DOWN_CONF_LEVEL_HIGH');
await approveCommand();
}
}
}
} else {
if (gettingCurrentImage) {
if (!isFoundFace.value) {
return;
}
var ft = await luxand!.getFaceTemplate(image);
var png = await convertYUV420toImageColor(image);
if (png != null) {
templates.add(TemplateModel(face: ft[1], eye: ft[0]));
faces.value.add(png);
faces.refresh();
if (faces.length >= 3) {
livenessMode.value = true;
isFoundFace.value = false;
commands = getCommands();
}
}
gettingCurrentImage = false;
} else {
var data = await luxand!.detectFace(image);
if (data == null) {
return;
}
var isFound = data[0] > 0;
isFoundFace.value = isFound;
if (isFound) {
faceX.value = data[0].toDouble();
faceY.value = data[1].toDouble();
faceW.value = data[2].toDouble();
age.value = data[3];
isMale.value = data[4] == 1;
}
}
}
});
}
List<ECommand> getCommands() {
var result = [ECommand.lookStraight];
while (true) {
if (result.contains(ECommand.lookUp) &&
result.contains(ECommand.lookDown) &&
result.contains(ECommand.turnLeft) &&
result.contains(ECommand.turnRight) &&
result.contains(ECommand.smile)) {
break;
}
do {
var cm = ECommand.fromInt(Random().nextInt(6));
if (!result.contains(cm) && cm != ECommand.lookStraight) {
result.add(cm);
result.add(ECommand.lookStraight);
break;
}
} while (true);
}
result.removeLast();
return result;
}
@override
void onInit() async {
super.onInit();
luxand = Get.put(LuxandController(licenseKey: licenseKey));
await luxand!.initialize();
await initCamera();
camController!.initialize().then((_) {
isCameraReady.value = true;
// Only open and close camera in iOS for low-tier device
if (Platform.isIOS) {
// _timer = Stream.periodic(const Duration(milliseconds: 500), (v) => v)
// .listen((count) async {
// _throttler.run(() async {
// controller.startImageStream((image) async {});
// Future.delayed(const Duration(milliseconds: 50), () async {
// await controller.stopImageStream();
// });
// });
// });
} else {
camController!.startImageStream(onAvailable);
}
});
}
getCurrentImage() async {
gettingCurrentImage = true;
}
Future<Image?> convertYUV420toImageColor(CameraImage image) async {
try {
final int width = image.width;
final int height = image.height;
final int uvRowStride = image.planes[1].bytesPerRow;
final int uvPixelStride = image.planes[1].bytesPerPixel!;
var img = imglib.Image(height: width, width: height);
// Fill image buffer with plane[0] from YUV420_888
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
final int uvIndex =
uvPixelStride * (x / 2).floor() + uvRowStride * (y / 2).floor();
final int index = y * width + x;
final yp = image.planes[0].bytes[index];
final up = image.planes[1].bytes[uvIndex];
final vp = image.planes[2].bytes[uvIndex];
// Calculate pixel color
int r = (yp + vp * 1436 / 1024 - 179).round().clamp(0, 255);
int g = (yp - up * 46549 / 131072 + 44 - vp * 93604 / 131072 + 91)
.round()
.clamp(0, 255);
int b = (yp + up * 1814 / 1024 - 227).round().clamp(0, 255);
// color: 0x FF FF FF FF
// A B G R
// img.data[index] = shift | (b << 16) | (g << 8) | r;
if (img.isBoundsSafe(height - y, x)) {
const shift = (0xFF << 24);
img.setPixelRgba(height - y, x, r, g, b, shift);
}
}
}
img = imglib.copyRotate(img, angle: -180);
img = imglib.flipHorizontal(img);
var encoder = imglib.JpegEncoder();
var bytes = encoder.encode(img);
return Image.memory(bytes);
} catch (e) {
print(">>>>>>>>>>>> ERROR:$e");
}
return null;
}
@override
void onClose() async {
super.onClose();
camController?.stopImageStream();
camController?.dispose();
await luxand!.freeResource();
}
}
enum ECommand {
lookStraight(0),
lookUp(1),
lookDown(2),
turnLeft(3),
turnRight(4),
smile(5);
final int value;
const ECommand(this.value);
factory ECommand.fromInt(int value) {
return values.firstWhere((light) => light.value == value,
orElse: () => ECommand.lookStraight);
}
}
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:myhr_facescan/enroll/controller.dart';
import 'package:myhr_facescan/enroll/rectangle_paint.dart';
class EnrollFace extends StatelessWidget {
const EnrollFace({super.key, required this.licenseKey});
final String licenseKey;
@override
Widget build(BuildContext context) {
var con = Get.put(EnrollController(licenseKey: licenseKey));
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Obx(() => con.isCameraReady.value
? GestureDetector(
onTap: con.getCurrentImage,
child: CameraPreview(
con.camController!,
child: con.livenessMode.value
? Column(
children: [
Text(con.commandName,
style: context.textTheme.headlineLarge)
],
)
: con.isFoundFace.value
? CustomPaint(
size: Size(
con.camController!.value.previewSize!
.height,
con.camController!.value.previewSize!
.width),
painter: RectanglePainter(
xc: con.faceX.value,
yc: con.faceY.value,
w: con.faceW.value,
paperWidth: con.camController!.value
.previewSize!.height,
paperHeight: con.camController!.value
.previewSize!.width,
age: con.age.value,
isMale: con.isMale.value),
)
: Container(),
),
)
: Container()),
Obx(() => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
...con.faces.value.map((e) => Container(
margin: const EdgeInsets.only(right: 8),
child: CircleAvatar(
radius: 25,
child: ClipRRect(
borderRadius: BorderRadius.circular(25),
child: Image(
image: e.image,
width: 48,
fit: BoxFit.cover)),
),
)),
],
))
],
),
);
}
}
import 'dart:ui';
import 'package:flutter/material.dart';
class RectanglePainter extends CustomPainter {
final double xc;
final double yc;
final double w;
final double paperWidth;
final double paperHeight;
final int age;
final bool isMale;
RectanglePainter(
{super.repaint,
required this.xc,
required this.yc,
required this.w,
required this.paperWidth,
required this.paperHeight,
required this.age,
required this.isMale});
@override
void paint(Canvas canvas, Size size) {
final xc = lerpDouble(0, size.width, this.xc / paperWidth)!;
final yc = lerpDouble(0, size.height, this.yc / paperHeight)!;
final width = lerpDouble(0, size.width, w / paperWidth)!;
var paint1 = Paint()
..color = Colors.blue.shade800
..style = PaintingStyle.stroke
..strokeWidth = 1;
canvas.drawRect(
Rect.fromCenter(center: Offset(xc, yc), width: width, height: width),
paint1);
const textStyle = TextStyle(
color: Colors.green,
// fontSize: 30,
);
var textSpan = TextSpan(
text: 'อายุ=$age, เพศ=${isMale ? 'ชาย' : 'หญิง'}',
style: textStyle,
);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
);
textPainter.layout(
minWidth: 0,
maxWidth: size.width,
);
final xCenter = xc - (width / 2);
final yCenter = yc - (width / 2) - 20;
textPainter.paint(canvas, Offset(xCenter, yCenter));
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
class TemplateModel {
final String face;
final String eye;
TemplateModel({required this.face, required this.eye});
}
import 'dart:ffi';
import 'dart:typed_data';
import 'package:camera/camera.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
class LuxandController extends GetxController {
var platform = const MethodChannel("myhr_facescan");
var isInitialized = false;
final String licenseKey;
LuxandController({required this.licenseKey});
initialize() async {
if (isInitialized) {
return;
}
DynamicLibrary.open("libfsdk.so");
int result = await platform
.invokeMethod("activateLuxand", {'licenseKey': licenseKey});
if (result == 0) {
isInitialized = true;
} else {
print('CANNOT INITIALIZE LUXAND: ${result}');
}
}
freeResource() async {
await platform.invokeMethod("freeResource");
}
Future<List<int>?> detectFace(CameraImage image) async {
List<int> strides = Int32List(image.planes.length * 2);
int index = 0;
final bytes = image.planes.map((plane) {
strides[index] = (plane.bytesPerRow);
index++;
strides[index] = (plane.bytesPerPixel)!;
index++;
return plane.bytes;
}).toList();
var result = await platform.invokeMethod<List<int>>("detectFace", {
'platforms': bytes,
'height': image.height,
'width': image.width,
'strides': strides
});
return result;
}
Future<List<String>> getFaceTemplate(CameraImage image) async {
List<int> strides = Int32List(image.planes.length * 2);
int index = 0;
final bytes = image.planes.map((plane) {
strides[index] = (plane.bytesPerRow);
index++;
strides[index] = (plane.bytesPerPixel)!;
index++;
return plane.bytes;
}).toList();
var data = await platform.invokeMethod<List<Object?>>("getFaceTemplate", {
'platforms': bytes,
'height': image.height,
'width': image.width,
'strides': strides
});
var result = [data![0].toString(), data[1].toString()];
return result;
}
Future<List<double>> getFaceAttribute(
CameraImage image, bool isExpression) async {
List<int> strides = Int32List(image.planes.length * 2);
int index = 0;
final bytes = image.planes.map((plane) {
strides[index] = (plane.bytesPerRow);
index++;
strides[index] = (plane.bytesPerPixel)!;
index++;
return plane.bytes;
}).toList();
var data = await platform.invokeMethod<List<double>>("getFaceAttribute", {
'platforms': bytes,
'height': image.height,
'width': image.width,
'strides': strides,
'isExpression': isExpression
});
return data!;
}
}
import 'myhr_facescan_platform_interface.dart';
class MyhrFacescan {
Future<String?> getPlatformVersion() {
return MyhrFacescanPlatform.instance.getPlatformVersion();
}
}
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'myhr_facescan_platform_interface.dart';
/// An implementation of [MyhrFacescanPlatform] that uses method channels.
class MethodChannelMyhrFacescan extends MyhrFacescanPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('myhr_facescan');
@override
Future<String?> getPlatformVersion() async {
final version =
await methodChannel.invokeMethod<String>('getPlatformVersion');
return version;
}
}
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'myhr_facescan_method_channel.dart';
abstract class MyhrFacescanPlatform extends PlatformInterface {
/// Constructs a MyhrFacescanPlatform.
MyhrFacescanPlatform() : super(token: _token);
static final Object _token = Object();
static MyhrFacescanPlatform _instance = MethodChannelMyhrFacescan();
/// The default instance of [MyhrFacescanPlatform] to use.
///
/// Defaults to [MethodChannelMyhrFacescan].
static MyhrFacescanPlatform get instance => _instance;
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [MyhrFacescanPlatform] when
/// they register themselves.
static set instance(MyhrFacescanPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
Future<String?> getPlatformVersion() {
throw UnimplementedError('platformVersion() has not been implemented.');
}
}
import 'dart:ui';
class Throttler {
Throttler({required this.milliSeconds});
final int milliSeconds;
int? lastActionTime;
void run(VoidCallback action) {
if (lastActionTime == null) {
action();
lastActionTime = DateTime.now().millisecondsSinceEpoch;
} else {
if (DateTime.now().millisecondsSinceEpoch - lastActionTime! >
(milliSeconds)) {
action();
lastActionTime = DateTime.now().millisecondsSinceEpoch;
}
}
}
}
name: myhr_facescan
description: Enroll face using luxand, verify real people by using active liveness detection
version: 0.1.0
homepage: https://mygit.myhr.co.th/NaeNaee/myhr-facescan
environment:
sdk: '>=3.3.0 <4.0.0'
flutter: '>=3.3.0'
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
camera: ^0.10.5+9
image: ^4.1.7
get:
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# This section identifies this Flutter project as a plugin project.
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
# which should be registered in the plugin registry. This is required for
# using method channels.
# The Android 'package' specifies package in which the registered class is.
# This is required for using method channels on Android.
# The 'ffiPlugin' specifies that native code should be built and bundled.
# This is required for using `dart:ffi`.
# All these are used by the tooling to maintain consistency when
# adding or updating assets for this project.
plugin:
platforms:
android:
package: myhr.facescan.myhr_facescan
pluginClass: MyhrFacescanPlugin
ios:
pluginClass: MyhrFacescanPlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# To add custom fonts to your plugin package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:myhr_facescan/myhr_facescan_method_channel.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
MethodChannelMyhrFacescan platform = MethodChannelMyhrFacescan();
const MethodChannel channel = MethodChannel('myhr_facescan');
setUp(() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(
channel,
(MethodCall methodCall) async {
return '42';
},
);
});
tearDown(() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(channel, null);
});
test('getPlatformVersion', () async {
expect(await platform.getPlatformVersion(), '42');
});
}
import 'package:flutter_test/flutter_test.dart';
import 'package:myhr_facescan/myhr_facescan.dart';
import 'package:myhr_facescan/myhr_facescan_platform_interface.dart';
import 'package:myhr_facescan/myhr_facescan_method_channel.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
class MockMyhrFacescanPlatform
with MockPlatformInterfaceMixin
implements MyhrFacescanPlatform {
@override
Future<String?> getPlatformVersion() => Future.value('42');
}
void main() {
final MyhrFacescanPlatform initialPlatform = MyhrFacescanPlatform.instance;
test('$MethodChannelMyhrFacescan is the default instance', () {
expect(initialPlatform, isInstanceOf<MethodChannelMyhrFacescan>());
});
test('getPlatformVersion', () async {
MyhrFacescan myhrFacescanPlugin = MyhrFacescan();
MockMyhrFacescanPlatform fakePlatform = MockMyhrFacescanPlatform();
MyhrFacescanPlatform.instance = fakePlatform;
expect(await myhrFacescanPlugin.getPlatformVersion(), '42');
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment