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(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(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; } } }