restore vault timeout timer for Android (#1220)
This commit is contained in:
parent
cdc08e7e8a
commit
56935a7210
@ -38,6 +38,7 @@ namespace Bit.Droid
|
|||||||
private IAppIdService _appIdService;
|
private IAppIdService _appIdService;
|
||||||
private IStorageService _storageService;
|
private IStorageService _storageService;
|
||||||
private IEventService _eventService;
|
private IEventService _eventService;
|
||||||
|
private PendingIntent _vaultTimeoutAlarmPendingIntent;
|
||||||
private PendingIntent _clearClipboardPendingIntent;
|
private PendingIntent _clearClipboardPendingIntent;
|
||||||
private PendingIntent _eventUploadPendingIntent;
|
private PendingIntent _eventUploadPendingIntent;
|
||||||
private AppOptions _appOptions;
|
private AppOptions _appOptions;
|
||||||
@ -50,6 +51,9 @@ namespace Bit.Droid
|
|||||||
var eventUploadIntent = new Intent(this, typeof(EventUploadReceiver));
|
var eventUploadIntent = new Intent(this, typeof(EventUploadReceiver));
|
||||||
_eventUploadPendingIntent = PendingIntent.GetBroadcast(this, 0, eventUploadIntent,
|
_eventUploadPendingIntent = PendingIntent.GetBroadcast(this, 0, eventUploadIntent,
|
||||||
PendingIntentFlags.UpdateCurrent);
|
PendingIntentFlags.UpdateCurrent);
|
||||||
|
var alarmIntent = new Intent(this, typeof(LockAlarmReceiver));
|
||||||
|
_vaultTimeoutAlarmPendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent,
|
||||||
|
PendingIntentFlags.UpdateCurrent);
|
||||||
var clearClipboardIntent = new Intent(this, typeof(ClearClipboardAlarmReceiver));
|
var clearClipboardIntent = new Intent(this, typeof(ClearClipboardAlarmReceiver));
|
||||||
_clearClipboardPendingIntent = PendingIntent.GetBroadcast(this, 0, clearClipboardIntent,
|
_clearClipboardPendingIntent = PendingIntent.GetBroadcast(this, 0, clearClipboardIntent,
|
||||||
PendingIntentFlags.UpdateCurrent);
|
PendingIntentFlags.UpdateCurrent);
|
||||||
@ -87,7 +91,20 @@ namespace Bit.Droid
|
|||||||
|
|
||||||
_broadcasterService.Subscribe(_activityKey, (message) =>
|
_broadcasterService.Subscribe(_activityKey, (message) =>
|
||||||
{
|
{
|
||||||
if (message.Command == "startEventTimer")
|
if (message.Command == "scheduleVaultTimeoutTimer")
|
||||||
|
{
|
||||||
|
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
||||||
|
var vaultTimeoutMinutes = (int)message.Data;
|
||||||
|
var vaultTimeoutMs = vaultTimeoutMinutes * 60000;
|
||||||
|
var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + vaultTimeoutMs + 10;
|
||||||
|
alarmManager.Set(AlarmType.RtcWakeup, triggerMs, _vaultTimeoutAlarmPendingIntent);
|
||||||
|
}
|
||||||
|
else if (message.Command == "cancelVaultTimeoutTimer")
|
||||||
|
{
|
||||||
|
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
||||||
|
alarmManager.Cancel(_vaultTimeoutAlarmPendingIntent);
|
||||||
|
}
|
||||||
|
else if (message.Command == "startEventTimer")
|
||||||
{
|
{
|
||||||
StartEventAlarm();
|
StartEventAlarm();
|
||||||
}
|
}
|
||||||
|
@ -758,7 +758,7 @@ namespace Bit.Droid.Services
|
|||||||
// be monotonic, and continues to tick even when the CPU is in power saving modes, so is the recommend
|
// be monotonic, and continues to tick even when the CPU is in power saving modes, so is the recommend
|
||||||
// basis for general purpose interval timing.
|
// basis for general purpose interval timing.
|
||||||
// ref: https://developer.android.com/reference/android/os/SystemClock#elapsedRealtime()
|
// ref: https://developer.android.com/reference/android/os/SystemClock#elapsedRealtime()
|
||||||
return SystemClock.ElapsedRealtime() / 1000;
|
return SystemClock.ElapsedRealtime();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DeleteDir(Java.IO.File dir)
|
private bool DeleteDir(Java.IO.File dir)
|
||||||
|
@ -185,7 +185,7 @@ namespace Bit.App
|
|||||||
var isLocked = await _vaultTimeoutService.IsLockedAsync();
|
var isLocked = await _vaultTimeoutService.IsLockedAsync();
|
||||||
if (!isLocked)
|
if (!isLocked)
|
||||||
{
|
{
|
||||||
await _storageService.SaveAsync(Constants.LastActiveKey, _deviceActionService.GetActiveTime());
|
await _storageService.SaveAsync(Constants.LastActiveTimeKey, _deviceActionService.GetActiveTime());
|
||||||
}
|
}
|
||||||
SetTabsPageFromAutofill(isLocked);
|
SetTabsPageFromAutofill(isLocked);
|
||||||
await SleptAsync();
|
await SleptAsync();
|
||||||
@ -211,6 +211,7 @@ namespace Bit.App
|
|||||||
private async void ResumedAsync()
|
private async void ResumedAsync()
|
||||||
{
|
{
|
||||||
await _vaultTimeoutService.CheckVaultTimeoutAsync();
|
await _vaultTimeoutService.CheckVaultTimeoutAsync();
|
||||||
|
_messagingService.Send("cancelVaultTimeoutTimer");
|
||||||
_messagingService.Send("startEventTimer");
|
_messagingService.Send("startEventTimer");
|
||||||
await ClearCacheIfNeededAsync();
|
await ClearCacheIfNeededAsync();
|
||||||
Prime();
|
Prime();
|
||||||
@ -302,7 +303,11 @@ namespace Bit.App
|
|||||||
vaultTimeout = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
vaultTimeout = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
||||||
}
|
}
|
||||||
vaultTimeout = vaultTimeout.GetValueOrDefault(-1);
|
vaultTimeout = vaultTimeout.GetValueOrDefault(-1);
|
||||||
if (vaultTimeout == 0)
|
if (vaultTimeout > 0)
|
||||||
|
{
|
||||||
|
_messagingService.Send("scheduleVaultTimeoutTimer", vaultTimeout.Value);
|
||||||
|
}
|
||||||
|
else if (vaultTimeout == 0)
|
||||||
{
|
{
|
||||||
var action = await _storageService.GetAsync<string>(Constants.VaultTimeoutActionKey);
|
var action = await _storageService.GetAsync<string>(Constants.VaultTimeoutActionKey);
|
||||||
if (action == "logOut")
|
if (action == "logOut")
|
||||||
|
@ -118,7 +118,7 @@ namespace Bit.App.Pages
|
|||||||
private void SaveActivity()
|
private void SaveActivity()
|
||||||
{
|
{
|
||||||
SetServices();
|
SetServices();
|
||||||
_storageService.SaveAsync(Constants.LastActiveKey, _deviceActionService.GetActiveTime());
|
_storageService.SaveAsync(Constants.LastActiveTimeKey, _deviceActionService.GetActiveTime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace Bit.App.Services
|
|||||||
Constants.DisableFaviconKey,
|
Constants.DisableFaviconKey,
|
||||||
Constants.ClearClipboardKey,
|
Constants.ClearClipboardKey,
|
||||||
Constants.AutofillDisableSavePromptKey,
|
Constants.AutofillDisableSavePromptKey,
|
||||||
Constants.LastActiveKey,
|
Constants.LastActiveTimeKey,
|
||||||
Constants.PushInitialPromptShownKey,
|
Constants.PushInitialPromptShownKey,
|
||||||
Constants.LastFileCacheClearKey,
|
Constants.LastFileCacheClearKey,
|
||||||
Constants.PushLastRegistrationDateKey,
|
Constants.PushLastRegistrationDateKey,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
public static string SyncOnRefreshKey = "syncOnRefresh";
|
public static string SyncOnRefreshKey = "syncOnRefresh";
|
||||||
public static string VaultTimeoutKey = "lockOption";
|
public static string VaultTimeoutKey = "lockOption";
|
||||||
public static string VaultTimeoutActionKey = "vaultTimeoutAction";
|
public static string VaultTimeoutActionKey = "vaultTimeoutAction";
|
||||||
public static string LastActiveKey = "lastActive";
|
public static string LastActiveTimeKey = "lastActiveTime";
|
||||||
public static string BiometricUnlockKey = "fingerprintUnlock";
|
public static string BiometricUnlockKey = "fingerprintUnlock";
|
||||||
public static string ProtectedPin = "protectedPin";
|
public static string ProtectedPin = "protectedPin";
|
||||||
public static string PinProtectedKey = "pinProtectedKey";
|
public static string PinProtectedKey = "pinProtectedKey";
|
||||||
|
@ -81,22 +81,23 @@ namespace Bit.Core.Services
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// This only returns null
|
// This only returns null
|
||||||
var vaultTimeout = _platformUtilsService.LockTimeout();
|
var vaultTimeoutMinutes = _platformUtilsService.LockTimeout();
|
||||||
if (vaultTimeout == null)
|
if (vaultTimeoutMinutes == null)
|
||||||
{
|
{
|
||||||
vaultTimeout = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
vaultTimeoutMinutes = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
||||||
}
|
}
|
||||||
if (vaultTimeout.GetValueOrDefault(-1) < 0)
|
if (vaultTimeoutMinutes.GetValueOrDefault(-1) < 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var lastActive = await _storageService.GetAsync<long?>(Constants.LastActiveKey);
|
var lastActiveTime = await _storageService.GetAsync<long?>(Constants.LastActiveTimeKey);
|
||||||
if (lastActive == null)
|
if (lastActiveTime == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var diff = _platformUtilsService.GetActiveTime() - lastActive;
|
var diffMs = _platformUtilsService.GetActiveTime() - lastActiveTime;
|
||||||
if (diff >= vaultTimeout * 60)
|
var vaultTimeoutMs = vaultTimeoutMinutes * 60000;
|
||||||
|
if (diffMs >= vaultTimeoutMs)
|
||||||
{
|
{
|
||||||
// Pivot based on saved action
|
// Pivot based on saved action
|
||||||
var action = await _storageService.GetAsync<string>(Constants.VaultTimeoutActionKey);
|
var action = await _storageService.GetAsync<string>(Constants.VaultTimeoutActionKey);
|
||||||
|
@ -432,9 +432,9 @@ namespace Bit.iOS.Core.Services
|
|||||||
|
|
||||||
public long GetActiveTime()
|
public long GetActiveTime()
|
||||||
{
|
{
|
||||||
// Fall back to UnixTimeSeconds in case this approach stops working. We'll lose clock-change protection but
|
// Fall back to UnixTimeMilliseconds in case this approach stops working. We'll lose clock-change
|
||||||
// the lock functionality will continue to work.
|
// protection but the lock functionality will continue to work.
|
||||||
return iOSHelpers.GetSystemUpTimeSeconds() ?? DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
return iOSHelpers.GetSystemUpTimeMilliseconds() ?? DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImagePicker_FinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs e)
|
private void ImagePicker_FinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs e)
|
||||||
|
@ -18,7 +18,7 @@ namespace Bit.iOS.Core.Utilities
|
|||||||
// includes sleep time.
|
// includes sleep time.
|
||||||
// ref: https://forums.xamarin.com/discussion/20006/access-to-sysctl-h
|
// ref: https://forums.xamarin.com/discussion/20006/access-to-sysctl-h
|
||||||
// ref: https://github.com/XLabs/Xamarin-Forms-Labs/blob/master/src/Platform/XLabs.Platform.iOS/Device/AppleDevice.cs
|
// ref: https://github.com/XLabs/Xamarin-Forms-Labs/blob/master/src/Platform/XLabs.Platform.iOS/Device/AppleDevice.cs
|
||||||
public static long? GetSystemUpTimeSeconds()
|
public static long? GetSystemUpTimeMilliseconds()
|
||||||
{
|
{
|
||||||
long? uptime = null;
|
long? uptime = null;
|
||||||
IntPtr pLen = default, pStr = default;
|
IntPtr pLen = default, pStr = default;
|
||||||
@ -34,7 +34,7 @@ namespace Bit.iOS.Core.Utilities
|
|||||||
var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
if (timeVal.sec > 0 && now > 0)
|
if (timeVal.sec > 0 && now > 0)
|
||||||
{
|
{
|
||||||
uptime = now - timeVal.sec;
|
uptime = (now - timeVal.sec) * 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -201,7 +201,7 @@ namespace Bit.iOS
|
|||||||
UIApplication.SharedApplication.KeyWindow.BringSubviewToFront(view);
|
UIApplication.SharedApplication.KeyWindow.BringSubviewToFront(view);
|
||||||
UIApplication.SharedApplication.KeyWindow.EndEditing(true);
|
UIApplication.SharedApplication.KeyWindow.EndEditing(true);
|
||||||
UIApplication.SharedApplication.SetStatusBarHidden(true, false);
|
UIApplication.SharedApplication.SetStatusBarHidden(true, false);
|
||||||
_storageService.SaveAsync(Constants.LastActiveKey, _deviceActionService.GetActiveTime());
|
_storageService.SaveAsync(Constants.LastActiveTimeKey, _deviceActionService.GetActiveTime());
|
||||||
_messagingService.Send("slept");
|
_messagingService.Send("slept");
|
||||||
base.DidEnterBackground(uiApplication);
|
base.DidEnterBackground(uiApplication);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user