mirror of
https://github.com/bitwarden/mobile
synced 2025-12-15 15:53:44 +00:00
mobile platform utils
This commit is contained in:
169
src/App/Services/MobilePlatformUtilsService.cs
Normal file
169
src/App/Services/MobilePlatformUtilsService.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
public class MobilePlatformUtilsService
|
||||
{
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
private const int DialogPromiseExpiration = 600000; // 10 minutes
|
||||
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly Dictionary<int, Tuple<TaskCompletionSource<bool>, DateTime>> _showDialogResolves =
|
||||
new Dictionary<int, Tuple<TaskCompletionSource<bool>, DateTime>>();
|
||||
|
||||
public MobilePlatformUtilsService(IDeviceActionService deviceActionService)
|
||||
{
|
||||
_deviceActionService = deviceActionService;
|
||||
|
||||
MessagingCenter.Subscribe<Xamarin.Forms.Application, Tuple<int, bool>>(
|
||||
Xamarin.Forms.Application.Current, "ShowDialogResolve", (sender, details) =>
|
||||
{
|
||||
var dialogId = details.Item1;
|
||||
var confirmed = details.Item2;
|
||||
if(_showDialogResolves.ContainsKey(dialogId))
|
||||
{
|
||||
var resolveObj = _showDialogResolves[dialogId].Item1;
|
||||
resolveObj.TrySetResult(confirmed);
|
||||
}
|
||||
|
||||
// Clean up old tasks
|
||||
var deleteIds = new HashSet<int>();
|
||||
foreach(var item in _showDialogResolves)
|
||||
{
|
||||
var age = DateTime.UtcNow - item.Value.Item2;
|
||||
if(age.TotalMilliseconds > DialogPromiseExpiration)
|
||||
{
|
||||
deleteIds.Add(item.Key);
|
||||
}
|
||||
}
|
||||
foreach(var id in deleteIds)
|
||||
{
|
||||
_showDialogResolves.Remove(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public string IdentityClientId => "mobile";
|
||||
|
||||
public Core.Enums.DeviceType GetDevice()
|
||||
{
|
||||
return Device.RuntimePlatform == Device.iOS ? Core.Enums.DeviceType.iOS : Core.Enums.DeviceType.Android;
|
||||
}
|
||||
|
||||
public string GetDeviceString()
|
||||
{
|
||||
return DeviceInfo.Model;
|
||||
}
|
||||
|
||||
public bool IsViewOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int? LockTimeout()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void LaunchUri(string uri, Dictionary<string, object> options = null)
|
||||
{
|
||||
if(uri.StartsWith("http://") || uri.StartsWith("https://"))
|
||||
{
|
||||
Browser.OpenAsync(uri, BrowserLaunchMode.External);
|
||||
}
|
||||
else
|
||||
{
|
||||
var launched = false;
|
||||
if(Device.RuntimePlatform == Device.Android && uri.StartsWith("androidapp://"))
|
||||
{
|
||||
launched = _deviceActionService.LaunchApp(uri);
|
||||
}
|
||||
if(!launched && (options?.ContainsKey("page") ?? false))
|
||||
{
|
||||
(options["page"] as Page).DisplayAlert(null, "", ""); // TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveFile()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
public string GetApplicationVersion()
|
||||
{
|
||||
return AppInfo.VersionString;
|
||||
}
|
||||
|
||||
public bool SupportsU2f()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ShowToast(string type, string title, string text, Dictionary<string, object> options = null)
|
||||
{
|
||||
ShowToast(type, title, new string[] { text }, options);
|
||||
}
|
||||
|
||||
public void ShowToast(string type, string title, string[] text, Dictionary<string, object> options = null)
|
||||
{
|
||||
if(text.Length > 0)
|
||||
{
|
||||
var longDuration = options != null && options.ContainsKey("longDuration") ?
|
||||
(bool)options["longDuration"] : false;
|
||||
_deviceActionService.Toast(text[0], longDuration);
|
||||
}
|
||||
}
|
||||
|
||||
public Task<bool> ShowDialogAsync(string text, string title = null, string confirmText = null,
|
||||
string cancelText = null, string type = null)
|
||||
{
|
||||
var dialogId = 0;
|
||||
lock(_random)
|
||||
{
|
||||
dialogId = _random.Next(0, int.MaxValue);
|
||||
}
|
||||
MessagingCenter.Send(Xamarin.Forms.Application.Current, "ShowAlert", new DialogDetails
|
||||
{
|
||||
Text = text,
|
||||
Title = title,
|
||||
ConfirmText = confirmText,
|
||||
CancelText = cancelText,
|
||||
Type = type,
|
||||
DialogId = dialogId
|
||||
});
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
_showDialogResolves.Add(dialogId, new Tuple<TaskCompletionSource<bool>, DateTime>(tcs, DateTime.UtcNow));
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
public bool IsDev()
|
||||
{
|
||||
return Core.Utilities.CoreHelpers.InDebugMode();
|
||||
}
|
||||
|
||||
public bool IsSelfHost()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task CopyToClipboardAsync(string text, Dictionary<string, object> options = null)
|
||||
{
|
||||
var clearMs = options != null && options.ContainsKey("clearMs") ? (int?)options["clearMs"] : null;
|
||||
await Clipboard.SetTextAsync(text);
|
||||
// TODO: send message 'copiedToClipboard'
|
||||
}
|
||||
|
||||
public async Task<string> ReadFromClipboardAsync(Dictionary<string, object> options = null)
|
||||
{
|
||||
return await Clipboard.GetTextAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user