2016-05-02 09:52:09 +03:00
|
|
|
|
using System;
|
|
|
|
|
using Android.App;
|
|
|
|
|
using Android.Content.PM;
|
|
|
|
|
using Android.Views;
|
|
|
|
|
using Android.OS;
|
|
|
|
|
using Bit.App.Abstractions;
|
|
|
|
|
using XLabs.Ioc;
|
2016-05-21 19:32:34 +03:00
|
|
|
|
using Plugin.Settings.Abstractions;
|
2016-07-02 01:54:00 +03:00
|
|
|
|
using Plugin.Connectivity.Abstractions;
|
2016-08-18 06:08:26 +03:00
|
|
|
|
using Android.Content;
|
2016-08-19 02:58:25 +03:00
|
|
|
|
using System.Reflection;
|
2016-08-20 03:42:33 +03:00
|
|
|
|
using Xamarin.Forms.Platform.Android;
|
|
|
|
|
using Xamarin.Forms;
|
2016-08-27 21:36:32 +03:00
|
|
|
|
using System.Threading.Tasks;
|
2017-06-08 23:22:11 +03:00
|
|
|
|
using Bit.App;
|
2017-06-28 06:33:13 +03:00
|
|
|
|
using Android.Nfc;
|
2017-07-22 22:38:08 +03:00
|
|
|
|
using System.IO;
|
2017-07-23 04:06:53 +03:00
|
|
|
|
using System.Linq;
|
2017-11-17 22:38:56 +03:00
|
|
|
|
using Bit.App.Models;
|
|
|
|
|
using Bit.App.Enums;
|
2016-05-02 09:52:09 +03:00
|
|
|
|
|
|
|
|
|
namespace Bit.Android
|
|
|
|
|
{
|
2018-03-18 00:26:10 +03:00
|
|
|
|
[Activity(ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, Exported = false)]
|
2016-08-20 03:42:33 +03:00
|
|
|
|
public class MainActivity : FormsAppCompatActivity
|
2016-05-02 09:52:09 +03:00
|
|
|
|
{
|
2016-08-14 07:15:47 +03:00
|
|
|
|
private const string HockeyAppId = "d3834185b4a643479047b86c65293d42";
|
2017-06-28 06:33:13 +03:00
|
|
|
|
private Java.Util.Regex.Pattern _otpPattern = Java.Util.Regex.Pattern.Compile("^.*?([cbdefghijklnrtuv]{32,64})$");
|
2017-07-21 18:39:22 +03:00
|
|
|
|
private IDeviceActionService _deviceActionService;
|
2018-05-24 18:41:57 +03:00
|
|
|
|
private IDeviceInfoService _deviceInfoService;
|
2018-06-04 16:20:38 +03:00
|
|
|
|
private IAppSettingsService _appSettingsService;
|
2017-07-21 18:39:22 +03:00
|
|
|
|
private ISettings _settings;
|
2017-11-21 21:26:06 +03:00
|
|
|
|
private AppOptions _appOptions;
|
2016-08-14 07:15:47 +03:00
|
|
|
|
|
2016-08-27 22:00:12 +03:00
|
|
|
|
protected override void OnCreate(Bundle bundle)
|
2016-05-02 09:52:09 +03:00
|
|
|
|
{
|
2017-02-10 05:06:47 +03:00
|
|
|
|
if(!Resolver.IsSet)
|
2017-01-28 07:13:28 +03:00
|
|
|
|
{
|
|
|
|
|
MainApplication.SetIoc(Application);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-07 06:27:14 +03:00
|
|
|
|
var policy = new StrictMode.ThreadPolicy.Builder().PermitAll().Build();
|
|
|
|
|
StrictMode.SetThreadPolicy(policy);
|
|
|
|
|
|
2016-08-20 03:42:33 +03:00
|
|
|
|
ToolbarResource = Resource.Layout.toolbar;
|
|
|
|
|
TabLayoutResource = Resource.Layout.tabs;
|
|
|
|
|
|
2016-05-02 09:52:09 +03:00
|
|
|
|
base.OnCreate(bundle);
|
2016-08-27 21:36:32 +03:00
|
|
|
|
|
|
|
|
|
// workaround for app compat bug
|
|
|
|
|
// ref https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity
|
2016-08-27 22:00:12 +03:00
|
|
|
|
Task.Delay(10).Wait();
|
2016-08-27 21:36:32 +03:00
|
|
|
|
|
2016-06-05 05:35:03 +03:00
|
|
|
|
Console.WriteLine("A OnCreate");
|
2017-07-24 22:04:31 +03:00
|
|
|
|
if(!App.Utilities.Helpers.InDebugMode())
|
|
|
|
|
{
|
|
|
|
|
Window.AddFlags(WindowManagerFlags.Secure);
|
|
|
|
|
}
|
2016-05-02 09:52:09 +03:00
|
|
|
|
|
2016-08-14 07:15:47 +03:00
|
|
|
|
var appIdService = Resolver.Resolve<IAppIdService>();
|
|
|
|
|
var authService = Resolver.Resolve<IAuthService>();
|
|
|
|
|
|
2018-01-10 17:28:30 +03:00
|
|
|
|
#if !FDROID
|
2016-08-14 07:15:47 +03:00
|
|
|
|
HockeyApp.Android.CrashManager.Register(this, HockeyAppId,
|
|
|
|
|
new HockeyAppCrashManagerListener(appIdService, authService));
|
2018-01-10 17:28:30 +03:00
|
|
|
|
#endif
|
2016-08-19 02:58:25 +03:00
|
|
|
|
|
2016-08-20 03:42:33 +03:00
|
|
|
|
Forms.Init(this, bundle);
|
2016-05-02 09:52:09 +03:00
|
|
|
|
|
2016-08-20 03:42:33 +03:00
|
|
|
|
typeof(Color).GetProperty("Accent", BindingFlags.Public | BindingFlags.Static)
|
|
|
|
|
.SetValue(null, Color.FromHex("d2d6de"));
|
2016-08-19 02:58:25 +03:00
|
|
|
|
|
2017-07-21 18:39:22 +03:00
|
|
|
|
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
|
2018-05-24 18:41:57 +03:00
|
|
|
|
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
|
2018-06-04 16:20:38 +03:00
|
|
|
|
_appSettingsService = Resolver.Resolve<IAppSettingsService>();
|
2017-07-21 18:39:22 +03:00
|
|
|
|
_settings = Resolver.Resolve<ISettings>();
|
2017-11-21 21:26:06 +03:00
|
|
|
|
_appOptions = GetOptions();
|
2016-05-21 19:32:34 +03:00
|
|
|
|
LoadApplication(new App.App(
|
2017-11-21 21:26:06 +03:00
|
|
|
|
_appOptions,
|
2016-05-21 19:32:34 +03:00
|
|
|
|
Resolver.Resolve<IAuthService>(),
|
2016-07-02 01:54:00 +03:00
|
|
|
|
Resolver.Resolve<IConnectivity>(),
|
2016-05-21 19:32:34 +03:00
|
|
|
|
Resolver.Resolve<IDatabaseService>(),
|
2016-07-01 03:08:34 +03:00
|
|
|
|
Resolver.Resolve<ISyncService>(),
|
2017-07-21 18:39:22 +03:00
|
|
|
|
_settings,
|
2016-08-04 07:06:09 +03:00
|
|
|
|
Resolver.Resolve<ILockService>(),
|
2017-02-06 07:55:46 +03:00
|
|
|
|
Resolver.Resolve<ILocalizeService>(),
|
2017-04-28 18:07:26 +03:00
|
|
|
|
Resolver.Resolve<IAppInfoService>(),
|
2018-06-04 16:20:38 +03:00
|
|
|
|
_appSettingsService,
|
2017-07-21 18:39:22 +03:00
|
|
|
|
_deviceActionService));
|
2016-08-18 06:08:26 +03:00
|
|
|
|
|
2017-11-21 21:26:06 +03:00
|
|
|
|
if(_appOptions?.Uri == null)
|
2017-06-29 19:11:07 +03:00
|
|
|
|
{
|
2017-11-21 21:26:06 +03:00
|
|
|
|
MessagingCenter.Subscribe<Xamarin.Forms.Application, bool>(Xamarin.Forms.Application.Current,
|
|
|
|
|
"ListenYubiKeyOTP", (sender, listen) => ListenYubiKey(listen));
|
2017-06-08 23:22:11 +03:00
|
|
|
|
|
2017-11-22 07:08:45 +03:00
|
|
|
|
MessagingCenter.Subscribe<Xamarin.Forms.Application>(Xamarin.Forms.Application.Current,
|
|
|
|
|
"FinishMainActivity", (sender) => Finish());
|
2017-11-17 17:21:12 +03:00
|
|
|
|
}
|
2016-05-02 09:52:09 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-06-05 05:35:03 +03:00
|
|
|
|
protected override void OnPause()
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("A OnPause");
|
|
|
|
|
base.OnPause();
|
2017-06-29 05:24:04 +03:00
|
|
|
|
ListenYubiKey(false);
|
2016-06-05 05:35:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnDestroy()
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("A OnDestroy");
|
|
|
|
|
base.OnDestroy();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnRestart()
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("A OnRestart");
|
|
|
|
|
base.OnRestart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnStart()
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("A OnStart");
|
|
|
|
|
base.OnStart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnStop()
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("A OnStop");
|
|
|
|
|
base.OnStop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnResume()
|
|
|
|
|
{
|
|
|
|
|
base.OnResume();
|
2017-02-04 07:21:40 +03:00
|
|
|
|
Console.WriteLine("A OnResume");
|
|
|
|
|
|
|
|
|
|
// workaround for app compat bug
|
|
|
|
|
// ref https://bugzilla.xamarin.com/show_bug.cgi?id=36907
|
|
|
|
|
Task.Delay(10).Wait();
|
2017-06-29 05:24:04 +03:00
|
|
|
|
|
2018-05-24 18:41:57 +03:00
|
|
|
|
if(_deviceInfoService.NfcEnabled)
|
2017-06-29 05:24:04 +03:00
|
|
|
|
{
|
2018-01-18 21:18:08 +03:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
MessagingCenter.Send(Xamarin.Forms.Application.Current, "ResumeYubiKey");
|
|
|
|
|
}
|
|
|
|
|
catch(Exception e)
|
|
|
|
|
{
|
|
|
|
|
System.Diagnostics.Debug.WriteLine(e);
|
|
|
|
|
}
|
2017-06-29 05:24:04 +03:00
|
|
|
|
}
|
2018-06-04 16:20:38 +03:00
|
|
|
|
|
|
|
|
|
if(_appSettingsService.Locked)
|
|
|
|
|
{
|
|
|
|
|
MessagingCenter.Send(Xamarin.Forms.Application.Current, "Resumed", false);
|
|
|
|
|
}
|
2017-06-29 05:24:04 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnNewIntent(Intent intent)
|
|
|
|
|
{
|
|
|
|
|
base.OnNewIntent(intent);
|
|
|
|
|
Console.WriteLine("A OnNewIntent");
|
|
|
|
|
ParseYubiKey(intent.DataString);
|
2016-06-05 05:35:03 +03:00
|
|
|
|
}
|
2016-08-18 06:08:26 +03:00
|
|
|
|
|
2017-07-23 04:06:53 +03:00
|
|
|
|
public async override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
|
2017-07-14 00:23:18 +03:00
|
|
|
|
{
|
2017-07-23 04:06:53 +03:00
|
|
|
|
if(requestCode == Constants.SelectFilePermissionRequestCode)
|
|
|
|
|
{
|
|
|
|
|
if(grantResults.Any(r => r != Permission.Granted))
|
|
|
|
|
{
|
|
|
|
|
MessagingCenter.Send(Xamarin.Forms.Application.Current, "SelectFileCameraPermissionDenied");
|
|
|
|
|
}
|
|
|
|
|
await _deviceActionService.SelectFileAsync();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-14 00:23:18 +03:00
|
|
|
|
ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-22 22:38:08 +03:00
|
|
|
|
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
|
|
|
|
{
|
|
|
|
|
if(requestCode == Constants.SelectFileRequestCode && resultCode == Result.Ok)
|
|
|
|
|
{
|
|
|
|
|
global::Android.Net.Uri uri = null;
|
2017-07-23 04:06:53 +03:00
|
|
|
|
string fileName = null;
|
|
|
|
|
if(data != null && data.Data != null)
|
2017-07-22 22:38:08 +03:00
|
|
|
|
{
|
|
|
|
|
uri = data.Data;
|
2017-07-23 04:06:53 +03:00
|
|
|
|
fileName = Utilities.GetFileName(ApplicationContext, uri);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// camera
|
|
|
|
|
var root = new Java.IO.File(global::Android.OS.Environment.ExternalStorageDirectory, "bitwarden");
|
|
|
|
|
var file = new Java.IO.File(root, "temp_camera_photo.jpg");
|
|
|
|
|
uri = global::Android.Net.Uri.FromFile(file);
|
|
|
|
|
fileName = $"photo_{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.jpg";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(uri == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using(var stream = ContentResolver.OpenInputStream(uri))
|
|
|
|
|
using(var memoryStream = new MemoryStream())
|
|
|
|
|
{
|
|
|
|
|
stream.CopyTo(memoryStream);
|
|
|
|
|
MessagingCenter.Send(Xamarin.Forms.Application.Current, "SelectFileResult",
|
|
|
|
|
new Tuple<byte[], string>(memoryStream.ToArray(), fileName ?? "unknown_file_name"));
|
2017-07-22 22:38:08 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-29 05:24:04 +03:00
|
|
|
|
private void ListenYubiKey(bool listen)
|
2017-06-28 06:33:13 +03:00
|
|
|
|
{
|
2018-05-24 18:41:57 +03:00
|
|
|
|
if(!_deviceInfoService.NfcEnabled)
|
2017-06-29 05:24:04 +03:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-06-28 06:33:13 +03:00
|
|
|
|
|
|
|
|
|
var adapter = NfcAdapter.GetDefaultAdapter(this);
|
2017-06-29 05:24:04 +03:00
|
|
|
|
if(listen)
|
|
|
|
|
{
|
|
|
|
|
var intent = new Intent(this, Class);
|
|
|
|
|
intent.AddFlags(ActivityFlags.SingleTop);
|
|
|
|
|
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);
|
|
|
|
|
|
|
|
|
|
// register for all NDEF tags starting with http och https
|
|
|
|
|
var ndef = new IntentFilter(NfcAdapter.ActionNdefDiscovered);
|
|
|
|
|
ndef.AddDataScheme("http");
|
|
|
|
|
ndef.AddDataScheme("https");
|
|
|
|
|
var filters = new IntentFilter[] { ndef };
|
|
|
|
|
|
|
|
|
|
// register for foreground dispatch so we'll receive tags according to our intent filters
|
|
|
|
|
adapter.EnableForegroundDispatch(this, pendingIntent, filters, null);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
adapter.DisableForegroundDispatch(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ParseYubiKey(string data)
|
|
|
|
|
{
|
|
|
|
|
if(data == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-06-28 06:33:13 +03:00
|
|
|
|
|
2017-06-29 05:24:04 +03:00
|
|
|
|
var otpMatch = _otpPattern.Matcher(data);
|
|
|
|
|
if(otpMatch.Matches())
|
2017-06-28 06:33:13 +03:00
|
|
|
|
{
|
2017-06-29 05:24:04 +03:00
|
|
|
|
var otp = otpMatch.Group(1);
|
|
|
|
|
MessagingCenter.Send(Xamarin.Forms.Application.Current, "GotYubiKeyOTP", otp);
|
2017-06-28 06:33:13 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-29 19:11:07 +03:00
|
|
|
|
|
2017-11-17 22:38:56 +03:00
|
|
|
|
private AppOptions GetOptions()
|
|
|
|
|
{
|
|
|
|
|
var options = new AppOptions
|
|
|
|
|
{
|
|
|
|
|
Uri = Intent.GetStringExtra("uri") ?? Intent.GetStringExtra("autofillFrameworkUri"),
|
2017-12-20 08:11:15 +03:00
|
|
|
|
MyVaultTile = Intent.GetBooleanExtra("myVaultTile", false),
|
2017-11-17 22:38:56 +03:00
|
|
|
|
FromAutofillFramework = Intent.GetBooleanExtra("autofillFramework", false)
|
|
|
|
|
};
|
|
|
|
|
|
2017-11-21 00:07:33 +03:00
|
|
|
|
var fillType = Intent.GetIntExtra("autofillFrameworkFillType", 0);
|
|
|
|
|
if(fillType > 0)
|
|
|
|
|
{
|
|
|
|
|
options.FillType = (CipherType)fillType;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-17 22:38:56 +03:00
|
|
|
|
if(Intent.GetBooleanExtra("autofillFrameworkSave", false))
|
|
|
|
|
{
|
|
|
|
|
options.SaveType = (CipherType)Intent.GetIntExtra("autofillFrameworkType", 0);
|
2017-11-18 01:15:42 +03:00
|
|
|
|
options.SaveName = Intent.GetStringExtra("autofillFrameworkName");
|
2017-11-17 22:38:56 +03:00
|
|
|
|
options.SaveUsername = Intent.GetStringExtra("autofillFrameworkUsername");
|
|
|
|
|
options.SavePassword = Intent.GetStringExtra("autofillFrameworkPassword");
|
2017-11-19 07:04:21 +03:00
|
|
|
|
options.SaveCardName = Intent.GetStringExtra("autofillFrameworkCardName");
|
|
|
|
|
options.SaveCardNumber = Intent.GetStringExtra("autofillFrameworkCardNumber");
|
|
|
|
|
options.SaveCardExpMonth = Intent.GetStringExtra("autofillFrameworkCardExpMonth");
|
|
|
|
|
options.SaveCardExpYear = Intent.GetStringExtra("autofillFrameworkCardExpYear");
|
|
|
|
|
options.SaveCardCode = Intent.GetStringExtra("autofillFrameworkCardCode");
|
2017-11-17 22:38:56 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return options;
|
|
|
|
|
}
|
2016-05-02 09:52:09 +03:00
|
|
|
|
}
|
|
|
|
|
}
|