public FingerprintService(IObservable <Unit> applicationActivated, FuncAsync <string> description, IScheduler dispatcher, IScheduler backgroundScheduler, bool fallbackOnPasscodeAuthentication = false)
        {
            applicationActivated.Validation().NotNull(nameof(applicationActivated));
            description.Validation().NotNull(nameof(description));
            dispatcher.Validation().NotNull(nameof(dispatcher));
            backgroundScheduler.Validation().NotNull(nameof(backgroundScheduler));

            _description = description;

            _dispatcher = dispatcher;

            _asyncLock = new AsyncLock();

            _isSupported =
                applicationActivated
                .ObserveOn(backgroundScheduler)
                .StartWith(backgroundScheduler, Unit.Default)
                .Select(_ => CheckSupport())
                .Replay(1, backgroundScheduler)
                .RefCount();

            _isEnabled =
                _isSupported
                .Select(isSupported => isSupported && CheckEnrollment())
                .Replay(1, backgroundScheduler)
                .RefCount();

            _fallbackOnPasscodeAuthentication = fallbackOnPasscodeAuthentication;
        }
Example #2
0
        public FingerprintService(
            FragmentActivity fragmentActivity,
            Context applicationContext,
            IObservable <Unit> applicationActivated,
            CoreDispatcher dispatcher,
            IScheduler backgroundScheduler,
            FuncAsync <BiometricPrompt.PromptInfo> promptInfoBuilder)
        {
            fragmentActivity.Validation().NotNull(nameof(fragmentActivity));
            applicationActivated.Validation().NotNull(nameof(applicationActivated));
            backgroundScheduler.Validation().NotNull(nameof(backgroundScheduler));
            _dispatcher        = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
            _promptInfoBuilder = promptInfoBuilder ?? throw new ArgumentNullException(nameof(promptInfoBuilder));

            var executor = ContextCompat.GetMainExecutor(applicationContext);
            var callback = new AuthenticationCallback(OnAuthenticationSucceeded, OnAuthenticationFailed, OnAuthenticationError);

            _BiometricPrompt  = new BiometricPrompt(fragmentActivity, executor, callback);
            _BiometricManager = BiometricManager.From(Application.Context);

            _keyStore = KeyStore.GetInstance(ANDROID_KEYSTORE);
            _keyStore.Load(null);

            _canAuthenticate =
                applicationActivated
                .ObserveOn(backgroundScheduler)
                .StartWith(backgroundScheduler, Unit.Default)
                .Select(_ => _BiometricManager.CanAuthenticate())
                .Replay(1, backgroundScheduler)
                .RefCount();
        }
Example #3
0
        /// <summary>
        /// Комманда которая аттачится к ViewModel.IsBusy - если модель занята, то
        /// любая другая команда, кроме SimpleCommand не сработает.
        /// После того как команда выполнится, то IsBusy автоматически становится false,
        /// давая возможность другим командам выполняться
        /// </summary>
        /// <param name="vm">ViewModel которая будет блокироваться после нажатия</param>
        /// <param name="function">Действие которое будет выполнено</param>
        public LockCommand(BaseViewModel vm, FuncAsync function, bool isBusy = false)
        {
            viewModel           = vm ?? throw new Exception("ViewModel не должна быть null");
            isCommandCanBlocked = isBusy;

            if (isCommandCanBlocked)
            {
                func = async(arg) =>
                {
                    await function();

                    vm.IsBusy = false;
                }
            }
            ;
            else
            {
                func = async(arg) =>
                {
                    await function();

                    isEnable = true;
                    if (CanExecuteChanged != null)
                    {
                        CanExecuteChanged.Invoke(this, new EventArgs());
                    }
                }
            };
        }
Example #4
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="BiometryService" /> class.
        /// </summary>
        /// <param name="options">The <see cref="BiometryOptions" /> instance to use.</param>
        /// <param name="description">An enum of LAPolicy.</param>
        /// <param name="localAuthenticationPolicy">The <see cref="LAPolicy" /> to use.</param>
        public BiometryService(BiometryOptions options, FuncAsync <string> description, LAPolicy localAuthenticationPolicy = LAPolicy.DeviceOwnerAuthentication)
        {
            _options = options ?? new BiometryOptions();

            _description = description;

            _localAuthenticationPolicy = localAuthenticationPolicy;
        }
Example #5
0
        /// <summary>
        /// Prevents parallel execution of the FuncAsync
        /// </summary>
        /// <param name="func">Func to lock</param>
        /// <param name="mode">Mode to use for locking</param>
        /// <returns>A FuncAsync which cannot have nmultiple instance running at a same time</returns>
        public static FuncAsync <TResult> LockInvocation <TResult>(this FuncAsync <TResult> func, InvocationLockingMode mode = InvocationLockingMode.Share)
        {
            // Note: Do not use TaskCompletionSource, for strange reasons it cause app crashes on iOS (on SetException).
            // Prefer keep task by themselves instead of trying to replicate task state to a TaskCompletionSource.

            if (mode == InvocationLockingMode.Share)
            {
                var gate    = new object();
                var pending = default(Task <TResult>);

                return(async ct =>
                {
                    var created = false;
                    try
                    {
                        var task = pending;
                        if (task == null)
                        {
                            lock (gate)
                            {
                                task = pending;
                                if (task == null)
                                {
                                    created = true;
                                    task = pending = func(ct);
                                }
                            }
                        }

                        return await task;
                    }
                    finally
                    {
                        // Note: Keep trace of the creation and let to the initiator the responsibility to removed the task from pendings
                        // DO NOT auto remove at the end of the task itself: If the task run synchronously, we might TryRemove the task before it is actually added to the pendings.
                        if (created)
                        {
                            pending = null;
                        }
                    }
                });
            }
            else
            {
                var gate = new AsyncLock();

                return(async ct =>
                {
                    using (await gate.LockAsync(ct))
                    {
                        return await func(ct);
                    }
                });
            }
        }
Example #6
0
 /// <summary>
 /// Invoke the <paramref name="func"/> if not null.
 /// </summary>
 /// <param name="func">Func to invoke</param>
 /// <param name="ct">A CanellationToken</param>
 /// <param name="param">Parameter of func</param>
 /// <returns>The result of func, or default(TResult) if the func was null.</returns>
 public static async Task <TResult> SafeInvoke <TParam, TResult>(this FuncAsync <TParam, TResult> func, CancellationToken ct, TParam param)
 {
     if (func == null)
     {
         return(default(TResult));
     }
     else
     {
         return(await func(ct, param));
     }
 }
Example #7
0
        /// <summary>
        /// Prevents parallel execution of the FuncAsync for a SAME PARAMETER
        /// </summary>
        /// <param name="func">Func to lock</param>
        /// <param name="mode">Mode to use for locking FOR A SAME PARAMETER</param>
        /// <returns>A FuncAsync which cannot have nmultiple instance running at a same time</returns>
        public static FuncAsync <TParam, TResult> LockInvocation <TParam, TResult>(this FuncAsync <TParam, TResult> func, InvocationLockingMode mode = InvocationLockingMode.Share)
            where TParam : class
        {
            // Note: Do not use TaskCompletionSource, for strange reasons it cause app crashes on iOS (on SetException).
            // Prefer keep task by themselves instead of trying to replicate task state to a TaskCompletionSource.

            if (mode == InvocationLockingMode.Share)
            {
#if HAS_NO_CONCURRENT_DICT
                var pendings = new SynchronizedDictionary <TParam, Task <TResult> >();
#else
                var pendings = new System.Collections.Concurrent.ConcurrentDictionary <TParam, Task <TResult> >();
#endif

                return(async(ct, param) =>
                {
                    var created = false;
                    try
                    {
                        return await pendings.GetOrAdd(param, p =>
                        {
                            created = true;
                            return func(ct, p);
                        });
                    }
                    finally
                    {
                        // Note: Keep trace of the creation and let to the initiator the responsibility to removed the task from pendings
                        // DO NOT auto remove at the end of the task itself: If the task run synchronously, we might TryRemove the task before it is actually added to the pendings.
                        if (created)
                        {
                            Task <TResult> _;
                            pendings.TryRemove(param, out _);
                        }
                    }
                });
            }
            else
            {
                var gates = new ConditionalWeakTable <TParam, AsyncLock>();

                return(async(ct, param) =>
                {
                    var gate = gates.GetValue(param, _ => new AsyncLock());
                    using (await gate.LockAsync(ct))
                    {
                        return await func(ct, param);
                    }
                });
            }
        }
        /// <summary>
        /// Constructor using an <see cref="IObjectSerializer"/> for persistence.
        /// </summary>
        public LockedFileDataPersister(
            string fullFilename,
            IObjectSerializer serializer,
            int numberOfRetries = 3,
            int retryDelay      = 100)
        {
            _committedFile   = new FileInfo(fullFilename /*.Validation().NotNull(nameof(fullFilename))*/).FullName;
            _read            = async(ct, stream) => (T)serializer.FromStream(stream, typeof(T));
            _write           = async(ct, entity, stream) => serializer.WriteToStream(entity, typeof(T), stream, canDisposeStream: true);
            _numberOfRetries = numberOfRetries;
            _retryDelay      = retryDelay;

            // Create other working file names
            _oldFile  = _committedFile + ".old";
            _newFile  = _committedFile + ".new";
            _lockFile = _committedFile + ".lck";
        }
Example #9
0
        private async Task <TResult> BuildTaskAsync(FuncAsync <AsyncOperation <TResult>, TResult> taskBuilder)
        {
            Status = AsyncStatus.Started;

            try
            {
                var result = await taskBuilder(_cts.Token, this);

                Status = AsyncStatus.Completed;
                return(result);
            }
            catch (Exception e)
            {
                ErrorCode = e;
                Status    = AsyncStatus.Error;
                throw;
            }
        }
        /// <summary>
        /// Constructor with callbacks for read & write operations.
        /// </summary>
        public LockedFileDataPersister(
            string fullFilename,
            FuncAsync <Stream, T> read,
            ActionAsync <T, Stream> write,
            int numberOfRetries = 3,
            int retryDelay      = 100)
        {
            _committedFile   = new FileInfo(fullFilename /*.Validation().NotNull(nameof(fullFilename))*/).FullName;
            _read            = read;
            _write           = write;
            _numberOfRetries = numberOfRetries;
            _retryDelay      = retryDelay;

            // Create other working file names
            _oldFile  = _committedFile + ".old";
            _newFile  = _committedFile + ".new";
            _lockFile = _committedFile + ".lck";
        }
Example #11
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="BiometryService" /> class.
        /// </summary>
        /// <param name="fragmentActivity"></param>
        /// <param name="dispatcher"></param>
        /// <param name="promptInfoBuilder"></param>
        /// <param name="authenticators"></param>
        public BiometryService(
            FragmentActivity fragmentActivity,
            CoreDispatcher dispatcher,
            FuncAsync <BiometricPrompt.PromptInfo> promptInfoBuilder)
        {
            fragmentActivity.Validation().NotNull(nameof(fragmentActivity));
            _dispatcher        = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
            _promptInfoBuilder = promptInfoBuilder ?? throw new ArgumentNullException(nameof(promptInfoBuilder));

            _applicationContext = Application.Context;
            var executor = ContextCompat.GetMainExecutor(_applicationContext);
            var callback = new AuthenticationCallback(OnAuthenticationSucceeded, OnAuthenticationFailed, OnAuthenticationError);

            _biometricPrompt  = new BiometricPrompt(fragmentActivity, executor, callback);
            _biometricManager = BiometricManager.From(_applicationContext);

            _keyStore = KeyStore.GetInstance(ANDROID_KEYSTORE);
            _keyStore.Load(null);
        }
        /// <summary>
        /// Creates a parameter-less memoizer for the the specified task provider. The task provider is guaranteed to be executed only once.
        /// </summary>
        /// <typeparam name="T">The return value type</typeparam>
        /// <param name="func">A function that will call the create the task.</param>
        /// <returns>A function that will return a task </returns>
        public static FuncAsync <T> AsMemoized <T>(this FuncAsync <T> func)
        {
            Task <T> value = null;
            object   gate  = new object();

            return(ct =>
            {
                if (value == null)
                {
                    lock (gate)
                    {
                        if (value == null)
                        {
                            value = Funcs.Create(async ct2 =>
                            {
                                try
                                {
                                    return await func(ct2);
                                }
                                catch (OperationCanceledException)
                                {
                                    lock (gate)
                                    {
                                        value = null;
                                    }

                                    throw;
                                }
                            })(ct);
                        }
                    }
                }

                return value;
            });
        }
        /// <summary>
        /// Creates a memoizer with one parameter for the the specified task provider. The task provider is guaranteed to be executed only once per parameter instance.
        /// </summary>
        /// <typeparam name="TResult">The return value type</typeparam>
        /// <typeparam name="TParam"></typeparam>
        /// <param name="func">A function that will call the create the task.</param>
        /// <returns>A function that will return a task </returns>
        public static FuncAsync <TParam, TResult> AsMemoized <TParam, TResult>(this FuncAsync <TParam, TResult> func)
        {
#if HAS_NO_CONCURRENT_DICT
            var values = new SynchronizedDictionary <TParam, FuncAsync <TResult> >();
#else
            var values = new System.Collections.Concurrent.ConcurrentDictionary <TParam, FuncAsync <TResult> >();
#endif
            // It's safe to use default(TParam) as this won't get called anyway if TParam is a value type.
            var nullValue = Funcs.CreateAsyncMemoized(ct => func(ct, default(TParam)));

            return((ct, param) =>
            {
                if (param == null)
                {
                    return nullValue(ct);
                }
                else
                {
                    var memoizedFunc = values.GetOrAdd(param, p => Funcs.CreateAsyncMemoized(c => func(c, p)));

                    return memoizedFunc(ct);
                }
            });
        }
Example #14
0
        internal void SetDataProvider(string formatId, FuncAsync <object> delayRenderer)
        {
            SetData(formatId, new DataProviderHandler(SetDataCore));

            async void SetDataCore(DataProviderRequest request)
            {
                var deferral = request.GetDeferral();

                try
                {
                    var data = await delayRenderer(request.CancellationToken);

                    request.SetData(data);
                }
                catch (Exception e)
                {
                    this.Log().Error($"Failed to asynchronously retrieve the data for od '{formatId}'", e);
                }
                finally
                {
                    deferral.Complete();
                }
            }
        }
Example #15
0
 internal static void Initialize(FuncAsync <string, bool> getter, FuncAsync <string, bool> checkPermission)
 {
     _tryGetPermission = getter;
     _checkPermission  = checkPermission;
 }
Example #16
0
 public static AsyncOperationWithProgress <TResult, TProgress> FromFuncAsync <TResult, TProgress>(FuncAsync <AsyncOperationWithProgress <TResult, TProgress>, TResult> builder)
 => new AsyncOperationWithProgress <TResult, TProgress>(builder);
Example #17
0
 CurryLast <T1, T2, T3, TResult>(this FuncAsync <T1, T2, T3, TResult> func, T3 last)
 {
     return((CancellationToken ct, T1 first, T2 second) => func(ct, first, second, last));
 }
Example #18
0
 CurryFirst <T1, T2, TResult>(this FuncAsync <T1, T2, TResult> func, T1 first)
 {
     return((CancellationToken ct, T2 last) => func(ct, first, last));
 }
Example #19
0
 Curry <T, TResult>(this FuncAsync <T, TResult> func, T value)
 {
     return(ct => func(ct, value));
 }
Example #20
0
 /// <summary>
 /// Creates a parameterless memoized task providing function. <seealso cref="Uno.Extensions.FuncMemoizeExtensions"/>
 /// </summary>
 /// <typeparam name="TResult">The returned type</typeparam>
 /// <param name="function">The source function</param>
 /// <returns>A function</returns>
 public static FuncAsync <TParam, TResult> CreateAsyncMemoized <TParam, TResult>(FuncAsync <TParam, TResult> function)
 {
     return(function.AsMemoized());
 }
Example #21
0
 /// <summary>
 /// Creates a parameterized cancellable async function.
 /// </summary>
 /// <typeparam name="TResult">The returned type</typeparam>
 /// <param name="function">The source function</param>
 /// <returns>A function</returns>
 public static FuncAsync <TParam1, TParam2, TResult> CreateAsync <TParam1, TParam2, TResult>(FuncAsync <TParam1, TParam2, TResult> function)
 {
     return(function);
 }
Example #22
0
 public AsyncOperation(FuncAsync <AsyncOperation <TResult>, TResult> taskBuilder)
 {
     Task = BuildTaskAsync(taskBuilder);
 }
Example #23
0
 public static AsyncOperation <TResult> FromTask(FuncAsync <AsyncOperation <TResult>, TResult> builder)
 => new AsyncOperation <TResult>(builder);
 public AsyncOperationWithProgress(FuncAsync <AsyncOperationWithProgress <TResult, TProgress>, TResult> taskBuilder)
     : base(Wrap(taskBuilder))
 {
 }