mirror of
https://github.com/bitwarden/mobile.git
synced 2024-11-22 11:35:21 +01:00
dispose nodes instead of manual GC
This commit is contained in:
parent
1d23bcc979
commit
c01d02de27
@ -51,9 +51,6 @@ namespace Bit.Android
|
|||||||
new Browser("com.ksmobile.cb", "address_bar_edit_text")
|
new Browser("com.ksmobile.cb", "address_bar_edit_text")
|
||||||
}.ToDictionary(n => n.PackageName);
|
}.ToDictionary(n => n.PackageName);
|
||||||
|
|
||||||
private long _lastGc = 0;
|
|
||||||
private int _eventCounter = 0;
|
|
||||||
|
|
||||||
public override void OnAccessibilityEvent(AccessibilityEvent e)
|
public override void OnAccessibilityEvent(AccessibilityEvent e)
|
||||||
{
|
{
|
||||||
var root = RootInActiveWindow;
|
var root = RootInActiveWindow;
|
||||||
@ -64,10 +61,13 @@ namespace Bit.Android
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
var testNodes = GetWindowNodes(root, e, n => n.ViewIdResourceName != null && n.Text != null)
|
var testNodes = GetWindowNodes(root, e, n => n.ViewIdResourceName != null && n.Text != null, false);
|
||||||
.Select(n => new { id = n.ViewIdResourceName, text = n.Text });
|
var testNodesData = testNodes.Select(n => new { id = n.ViewIdResourceName, text = n.Text });
|
||||||
|
testNodes.Dispose();
|
||||||
|
testNodes = null;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var notificationManager = ((NotificationManager)GetSystemService(NotificationService));
|
||||||
switch(e.EventType)
|
switch(e.EventType)
|
||||||
{
|
{
|
||||||
case EventTypes.WindowContentChanged:
|
case EventTypes.WindowContentChanged:
|
||||||
@ -76,11 +76,11 @@ namespace Bit.Android
|
|||||||
|
|
||||||
if(e.PackageName == BitwardenPackage)
|
if(e.PackageName == BitwardenPackage)
|
||||||
{
|
{
|
||||||
CancelNotification();
|
notificationManager.Cancel(AutoFillNotificationId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var passwordNodes = GetWindowNodes(root, e, n => n.Password);
|
var passwordNodes = GetWindowNodes(root, e, n => n.Password, false);
|
||||||
if(passwordNodes.Count > 0)
|
if(passwordNodes.Count > 0)
|
||||||
{
|
{
|
||||||
var uri = GetUri(root);
|
var uri = GetUri(root);
|
||||||
@ -88,16 +88,18 @@ namespace Bit.Android
|
|||||||
{
|
{
|
||||||
if(NeedToAutofill(AutofillActivity.LastCredentials, uri))
|
if(NeedToAutofill(AutofillActivity.LastCredentials, uri))
|
||||||
{
|
{
|
||||||
var allEditTexts = GetWindowNodes(root, e, n => EditText(n));
|
var allEditTexts = GetWindowNodes(root, e, n => EditText(n), false);
|
||||||
var usernameEditText = allEditTexts.TakeWhile(n => !n.Password).LastOrDefault();
|
var usernameEditText = allEditTexts.TakeWhile(n => !n.Password).LastOrDefault();
|
||||||
FillCredentials(usernameEditText, passwordNodes);
|
FillCredentials(usernameEditText, passwordNodes);
|
||||||
|
|
||||||
|
allEditTexts.Dispose();
|
||||||
allEditTexts = null;
|
allEditTexts = null;
|
||||||
|
usernameEditText.Dispose();
|
||||||
usernameEditText = null;
|
usernameEditText = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NotifyToAutofill(uri);
|
NotifyToAutofill(uri, notificationManager);
|
||||||
cancelNotification = false;
|
cancelNotification = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,27 +107,23 @@ namespace Bit.Android
|
|||||||
AutofillActivity.LastCredentials = null;
|
AutofillActivity.LastCredentials = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
passwordNodes.Dispose();
|
||||||
passwordNodes = null;
|
passwordNodes = null;
|
||||||
|
|
||||||
if(cancelNotification)
|
if(cancelNotification)
|
||||||
{
|
{
|
||||||
CancelNotification();
|
notificationManager.Cancel(AutoFillNotificationId);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notificationManager.Dispose();
|
||||||
|
notificationManager = null;
|
||||||
|
root.Dispose();
|
||||||
root = null;
|
root = null;
|
||||||
|
e.Dispose();
|
||||||
// Do some manual GCing
|
|
||||||
_eventCounter++;
|
|
||||||
var now = Java.Lang.JavaSystem.CurrentTimeMillis();
|
|
||||||
if((now - _lastGc) > 60000 && _eventCounter >= 20)
|
|
||||||
{
|
|
||||||
GC.Collect(0);
|
|
||||||
_lastGc = now;
|
|
||||||
_eventCounter = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnInterrupt()
|
public override void OnInterrupt()
|
||||||
@ -133,12 +131,6 @@ namespace Bit.Android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CancelNotification()
|
|
||||||
{
|
|
||||||
var notificationManager = ((NotificationManager)GetSystemService(NotificationService));
|
|
||||||
notificationManager.Cancel(AutoFillNotificationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetUri(AccessibilityNodeInfo root)
|
private string GetUri(AccessibilityNodeInfo root)
|
||||||
{
|
{
|
||||||
var uri = string.Concat(App.Constants.AndroidAppProtocol, root.PackageName);
|
var uri = string.Concat(App.Constants.AndroidAppProtocol, root.PackageName);
|
||||||
@ -149,6 +141,8 @@ namespace Bit.Android
|
|||||||
if(addressNode != null)
|
if(addressNode != null)
|
||||||
{
|
{
|
||||||
uri = ExtractUri(uri, addressNode, SupportedBrowsers[root.PackageName]);
|
uri = ExtractUri(uri, addressNode, SupportedBrowsers[root.PackageName]);
|
||||||
|
addressNode.Dispose();
|
||||||
|
addressNode = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +204,7 @@ namespace Bit.Android
|
|||||||
return n.ClassName != null && n.ClassName.Contains("EditText");
|
return n.ClassName != null && n.ClassName.Contains("EditText");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NotifyToAutofill(string uri)
|
private void NotifyToAutofill(string uri, NotificationManager notificationManager)
|
||||||
{
|
{
|
||||||
var intent = new Intent(this, typeof(AutofillActivity));
|
var intent = new Intent(this, typeof(AutofillActivity));
|
||||||
intent.PutExtra("uri", uri);
|
intent.PutExtra("uri", uri);
|
||||||
@ -232,8 +226,10 @@ namespace Bit.Android
|
|||||||
Resource.Color.primary));
|
Resource.Color.primary));
|
||||||
}
|
}
|
||||||
|
|
||||||
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
|
|
||||||
notificationManager.Notify(AutoFillNotificationId, builder.Build());
|
notificationManager.Notify(AutoFillNotificationId, builder.Build());
|
||||||
|
|
||||||
|
builder.Dispose();
|
||||||
|
builder = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FillCredentials(AccessibilityNodeInfo usernameNode, IEnumerable<AccessibilityNodeInfo> passwordNodes)
|
private void FillCredentials(AccessibilityNodeInfo usernameNode, IEnumerable<AccessibilityNodeInfo> passwordNodes)
|
||||||
@ -257,24 +253,31 @@ namespace Bit.Android
|
|||||||
editTextNode.PerformAction(global::Android.Views.Accessibility.Action.SetText, bundle);
|
editTextNode.PerformAction(global::Android.Views.Accessibility.Action.SetText, bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AccessibilityNodeInfo> GetWindowNodes(AccessibilityNodeInfo n,
|
private NodeList GetWindowNodes(AccessibilityNodeInfo n, AccessibilityEvent e,
|
||||||
AccessibilityEvent e, Func<AccessibilityNodeInfo, bool> condition, List<AccessibilityNodeInfo> nodes = null)
|
Func<AccessibilityNodeInfo, bool> condition, bool disposeIfUnused, NodeList nodes = null)
|
||||||
{
|
{
|
||||||
if(nodes == null)
|
if(nodes == null)
|
||||||
{
|
{
|
||||||
nodes = new List<AccessibilityNodeInfo>();
|
nodes = new NodeList();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n != null)
|
if(n != null)
|
||||||
{
|
{
|
||||||
|
var dispose = disposeIfUnused;
|
||||||
if(n.WindowId == e.WindowId && !(n.ViewIdResourceName?.StartsWith(SystemUiPackage) ?? false) && condition(n))
|
if(n.WindowId == e.WindowId && !(n.ViewIdResourceName?.StartsWith(SystemUiPackage) ?? false) && condition(n))
|
||||||
{
|
{
|
||||||
|
dispose = false;
|
||||||
nodes.Add(n);
|
nodes.Add(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var i = 0; i < n.ChildCount; i++)
|
for(var i = 0; i < n.ChildCount; i++)
|
||||||
{
|
{
|
||||||
GetWindowNodes(n.GetChild(i), e, condition, nodes);
|
GetWindowNodes(n.GetChild(i), e, condition, true, nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dispose)
|
||||||
|
{
|
||||||
|
n.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,5 +302,16 @@ namespace Bit.Android
|
|||||||
public string UriViewId { get; set; }
|
public string UriViewId { get; set; }
|
||||||
public Func<string, string> GetUriFunction { get; set; } = (s) => s;
|
public Func<string, string> GetUriFunction { get; set; } = (s) => s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class NodeList : List<AccessibilityNodeInfo>, IDisposable
|
||||||
|
{
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
foreach(var item in this)
|
||||||
|
{
|
||||||
|
item.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user