119 lines
4.3 KiB
C#
119 lines
4.3 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Bit.App.Utilities;
|
|
using Bit.Core.Services;
|
|
using UIKit;
|
|
using Xamarin.Forms;
|
|
using Xamarin.Forms.Platform.iOS;
|
|
|
|
namespace Bit.iOS.Core.Utilities
|
|
{
|
|
public static class iOSHelpers
|
|
{
|
|
[DllImport(ObjCRuntime.Constants.SystemLibrary)]
|
|
internal static extern int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string property, IntPtr output,
|
|
IntPtr oldLen, IntPtr newp, uint newLen);
|
|
|
|
// Returns the difference between when the system was booted and now in seconds, resulting in a duration that
|
|
// includes sleep time.
|
|
// 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
|
|
public static long? GetSystemUpTimeMilliseconds()
|
|
{
|
|
long? uptime = null;
|
|
IntPtr pLen = default, pStr = default;
|
|
try
|
|
{
|
|
var property = "kern.boottime";
|
|
pLen = Marshal.AllocHGlobal(sizeof(int));
|
|
sysctlbyname(property, IntPtr.Zero, pLen, IntPtr.Zero, 0);
|
|
var length = Marshal.ReadInt32(pLen);
|
|
pStr = Marshal.AllocHGlobal(length);
|
|
sysctlbyname(property, pStr, pLen, IntPtr.Zero, 0);
|
|
var timeVal = Marshal.PtrToStructure<TimeVal>(pStr);
|
|
var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
|
if (timeVal.sec > 0 && now > 0)
|
|
{
|
|
uptime = (now - timeVal.sec) * 1000;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.Instance.Exception(e);
|
|
}
|
|
finally
|
|
{
|
|
if (pLen != default)
|
|
{
|
|
Marshal.FreeHGlobal(pLen);
|
|
}
|
|
if (pStr != default)
|
|
{
|
|
Marshal.FreeHGlobal(pStr);
|
|
}
|
|
}
|
|
return uptime;
|
|
}
|
|
|
|
public static nfloat? GetAccessibleFont<T>(double size)
|
|
{
|
|
var pointSize = UIFontDescriptor.PreferredBody.PointSize;
|
|
if (size == Device.GetNamedSize(NamedSize.Large, typeof(T)))
|
|
{
|
|
pointSize *= 1.3f;
|
|
}
|
|
else if (size == Device.GetNamedSize(NamedSize.Small, typeof(T)))
|
|
{
|
|
pointSize *= .8f;
|
|
}
|
|
else if (size == Device.GetNamedSize(NamedSize.Micro, typeof(T)))
|
|
{
|
|
pointSize *= .6f;
|
|
}
|
|
else if (size != Device.GetNamedSize(NamedSize.Default, typeof(T)))
|
|
{
|
|
// not using dynamic font sizes, return
|
|
return null;
|
|
}
|
|
return pointSize;
|
|
}
|
|
|
|
public static void SetBottomBorder(UITextField control)
|
|
{
|
|
control.BorderStyle = UITextBorderStyle.None;
|
|
SetBottomBorder(control as UIView);
|
|
}
|
|
|
|
public static void SetBottomBorder(UITextView control)
|
|
{
|
|
SetBottomBorder(control as UIView);
|
|
}
|
|
|
|
private static void SetBottomBorder(UIView control)
|
|
{
|
|
var borderLine = new UIView
|
|
{
|
|
BackgroundColor = ThemeManager.GetResourceColor("BoxBorderColor").ToUIColor(),
|
|
TranslatesAutoresizingMaskIntoConstraints = false
|
|
};
|
|
control.AddSubview(borderLine);
|
|
control.AddConstraints(new NSLayoutConstraint[]
|
|
{
|
|
NSLayoutConstraint.Create(borderLine, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1, 1f),
|
|
NSLayoutConstraint.Create(borderLine, NSLayoutAttribute.Leading, NSLayoutRelation.Equal,
|
|
control, NSLayoutAttribute.Leading, 1, 0),
|
|
NSLayoutConstraint.Create(borderLine, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal,
|
|
control, NSLayoutAttribute.Trailing, 1, 0),
|
|
NSLayoutConstraint.Create(borderLine, NSLayoutAttribute.Top, NSLayoutRelation.Equal,
|
|
control, NSLayoutAttribute.Bottom, 1, 10f),
|
|
});
|
|
}
|
|
|
|
private struct TimeVal
|
|
{
|
|
public long sec;
|
|
public long usec;
|
|
}
|
|
}
|
|
}
|