public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e) { var filled = false; var uri = AccessibilityHelpers.GetUri(root); if (uri != null && !uri.Contains(BitwardenWebsite) && AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri)) { var allEditTexts = AccessibilityHelpers.GetWindowNodes(root, e, n => AccessibilityHelpers.EditText(n), false); var usernameEditText = AccessibilityHelpers.GetUsernameEditText(uri, allEditTexts); var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false); if (usernameEditText != null || passwordNodes.Count > 0) { AccessibilityHelpers.FillCredentials(usernameEditText, passwordNodes); filled = true; _lastAutoFillTime = Java.Lang.JavaSystem.CurrentTimeMillis(); AccessibilityHelpers.LastCredentials = null; } allEditTexts.Dispose(); passwordNodes.Dispose(); } if (AccessibilityHelpers.LastCredentials != null) { Task.Run(async() => { await Task.Delay(1000); AccessibilityHelpers.LastCredentials = null; }); } return(filled); }
public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e) { var filled = false; var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false); if (passwordNodes.Count > 0) { var uri = AccessibilityHelpers.GetUri(root); if (uri != null && !uri.Contains(BitwardenWebsite)) { if (AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri)) { AccessibilityHelpers.GetNodesAndFill(root, e, passwordNodes); filled = true; _lastAutoFillTime = Java.Lang.JavaSystem.CurrentTimeMillis(); } } AccessibilityHelpers.LastCredentials = null; } else if (AccessibilityHelpers.LastCredentials != null) { Task.Run(async() => { await Task.Delay(1000); AccessibilityHelpers.LastCredentials = null; }); } passwordNodes.Dispose(); return(filled); }
private void AdjustOverlayForScroll(AccessibilityNodeInfo root, AccessibilityEvent e) { if (_overlayView == null || _anchorViewHash <= 0) { return; } var anchorPosition = AccessibilityHelpers.GetOverlayAnchorPosition(_anchorViewHash, root, e); if (anchorPosition == null) { return; } if (anchorPosition.X == _lastAnchorX && anchorPosition.Y == _lastAnchorY) { return; } var layoutParams = AccessibilityHelpers.GetOverlayLayoutParams(); layoutParams.X = anchorPosition.X; layoutParams.Y = anchorPosition.Y; _windowManager.UpdateViewLayout(_overlayView, layoutParams); _lastAnchorX = anchorPosition.X; _lastAnchorY = anchorPosition.Y; System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Updated to X:{0} Y:{1}", layoutParams.X, layoutParams.Y); }
public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e, NotificationManager notificationManager, bool cancelNotification) { var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false); if (passwordNodes.Count > 0) { var uri = AccessibilityHelpers.GetUri(root); if (uri != null && !uri.Contains(BitwardenWebsite)) { if (AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri)) { AccessibilityHelpers.GetNodesAndFill(root, e, passwordNodes); } else { NotifyToAutofill(uri, notificationManager); cancelNotification = false; } } AccessibilityHelpers.LastCredentials = null; } else if (AccessibilityHelpers.LastCredentials != null) { Task.Run(async() => { await Task.Delay(1000); AccessibilityHelpers.LastCredentials = null; }); } passwordNodes.Dispose(); return(cancelNotification); }
private void OverlayPromptToAutofill(AccessibilityNodeInfo root, AccessibilityEvent e) { if (!AccessibilityHelpers.OverlayPermitted()) { System.Diagnostics.Debug.WriteLine(">>> Overlay Permission not granted"); Toast.MakeText(this, AppResources.AccessibilityOverlayPermissionAlert, ToastLength.Long).Show(); return; } if (_overlayView != null || _anchorNode != null || _overlayAnchorObserverRunning) { CancelOverlayPrompt(); } if (Java.Lang.JavaSystem.CurrentTimeMillis() - _lastAutoFillTime < 1000) { return; } var uri = AccessibilityHelpers.GetUri(root); if (string.IsNullOrWhiteSpace(uri)) { return; } var layoutParams = AccessibilityHelpers.GetOverlayLayoutParams(); var anchorPosition = AccessibilityHelpers.GetOverlayAnchorPosition(root, e.Source); layoutParams.X = anchorPosition.X; layoutParams.Y = anchorPosition.Y; if (_windowManager == null) { _windowManager = GetSystemService(WindowService).JavaCast <IWindowManager>(); } var intent = new Intent(this, typeof(AccessibilityActivity)); intent.PutExtra("uri", uri); intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop); _overlayView = AccessibilityHelpers.GetOverlayView(this); _overlayView.Click += (sender, eventArgs) => { CancelOverlayPrompt(); StartActivity(intent); }; _anchorNode = e.Source; _lastAnchorX = anchorPosition.X; _lastAnchorY = anchorPosition.Y; _windowManager.AddView(_overlayView, layoutParams); System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Added at X:{0} Y:{1}", layoutParams.X, layoutParams.Y); StartOverlayAnchorObserver(); }
private void AdjustOverlayForScroll() { if (_overlayView == null || _anchorNode == null) { CancelOverlayPrompt(); return; } var root = RootInActiveWindow; IEnumerable <AccessibilityWindowInfo> windows = null; if (Build.VERSION.SdkInt > BuildVersionCodes.Kitkat) { windows = Windows; } var anchorPosition = AccessibilityHelpers.GetOverlayAnchorPosition(_anchorNode, root, windows); if (anchorPosition == null) { CancelOverlayPrompt(); return; } else if (anchorPosition.X == -1 && anchorPosition.Y == -1) { if (_overlayView.Visibility != ViewStates.Gone) { _overlayView.Visibility = ViewStates.Gone; } return; } else if (anchorPosition.X == _lastAnchorX && anchorPosition.Y == _lastAnchorY) { if (_overlayView.Visibility != ViewStates.Visible) { _overlayView.Visibility = ViewStates.Visible; } return; } var layoutParams = AccessibilityHelpers.GetOverlayLayoutParams(); layoutParams.X = anchorPosition.X; layoutParams.Y = anchorPosition.Y; _lastAnchorX = anchorPosition.X; _lastAnchorY = anchorPosition.Y; _windowManager.UpdateViewLayout(_overlayView, layoutParams); if (_overlayView.Visibility != ViewStates.Visible) { _overlayView.Visibility = ViewStates.Visible; } System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Updated to X:{0} Y:{1}", layoutParams.X, layoutParams.Y); }
private void OnAutofillTileClick() { CancelOverlayPrompt(); var root = RootInActiveWindow; if (root != null && root.PackageName != BitwardenPackage && root.PackageName != AccessibilityHelpers.SystemUiPackage && !SkipPackage(root.PackageName)) { var uri = AccessibilityHelpers.GetUri(root); if (!string.IsNullOrWhiteSpace(uri)) { var intent = new Intent(this, typeof(AccessibilityActivity)); intent.PutExtra("uri", uri); intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop); StartActivity(intent); return; } } Toast.MakeText(this, AppResources.AutofillTileUriNotFound, ToastLength.Long).Show(); }
public override void OnAccessibilityEvent(AccessibilityEvent e) { try { var powerManager = GetSystemService(PowerService) as PowerManager; if (Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch && !powerManager.IsInteractive) { return; } else if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop && !powerManager.IsScreenOn) { return; } if (SkipPackage(e?.PackageName)) { if (e?.PackageName != "com.android.systemui") { CancelOverlayPrompt(); } return; } // AccessibilityHelpers.PrintTestData(RootInActiveWindow, e); AccessibilityNodeInfo root = null; switch (e.EventType) { case EventTypes.ViewFocused: case EventTypes.ViewClicked: if (e.Source == null || e.PackageName == BitwardenPackage) { CancelOverlayPrompt(); break; } root = RootInActiveWindow; if (root == null || root.PackageName != e.PackageName) { break; } if (!(e.Source?.Password ?? false) && !AccessibilityHelpers.IsUsernameEditText(root, e)) { CancelOverlayPrompt(); break; } if (ScanAndAutofill(root, e)) { CancelOverlayPrompt(); } else { OverlayPromptToAutofill(root, e); } break; case EventTypes.WindowContentChanged: case EventTypes.WindowStateChanged: if (AccessibilityHelpers.LastCredentials == null) { break; } if (e.PackageName == BitwardenPackage) { CancelOverlayPrompt(); break; } root = RootInActiveWindow; if (root == null || root.PackageName != e.PackageName) { break; } if (ScanAndAutofill(root, e)) { CancelOverlayPrompt(); } break; default: break; } } // Suppress exceptions so that service doesn't crash. catch (Exception ex) { System.Diagnostics.Debug.WriteLine(">>> {0}: {1}", ex.GetType(), ex.StackTrace); } }
public override void OnAccessibilityEvent(AccessibilityEvent e) { try { var powerManager = GetSystemService(PowerService) as PowerManager; if (Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch && !powerManager.IsInteractive) { return; } else if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop && !powerManager.IsScreenOn) { return; } if (SkipPackage(e?.PackageName)) { CancelOverlayPrompt(); return; } var root = RootInActiveWindow; if (root == null || root.PackageName != e.PackageName) { return; } // AccessibilityHelpers.PrintTestData(root, e); switch (e.EventType) { case EventTypes.ViewFocused: case EventTypes.ViewClicked: case EventTypes.ViewScrolled: var isKnownBroswer = AccessibilityHelpers.SupportedBrowsers.ContainsKey(root.PackageName); if (e.EventType == EventTypes.ViewClicked && isKnownBroswer) { break; } if (e.Source == null || e.PackageName == BitwardenPackage) { CancelOverlayPrompt(); break; } if (e.EventType == EventTypes.ViewScrolled) { AdjustOverlayForScroll(root, e); break; } else { var isUsernameEditText1 = AccessibilityHelpers.IsUsernameEditText(root, e); var isPasswordEditText1 = e.Source?.Password ?? false; if (!isUsernameEditText1 && !isPasswordEditText1) { CancelOverlayPrompt(); break; } if (ScanAndAutofill(root, e)) { CancelOverlayPrompt(); } else { OverlayPromptToAutofill(root, e); } } break; case EventTypes.WindowContentChanged: case EventTypes.WindowStateChanged: var isUsernameEditText2 = AccessibilityHelpers.IsUsernameEditText(root, e); var isPasswordEditText2 = e.Source?.Password ?? false; if (e.Source == null || isUsernameEditText2 || isPasswordEditText2) { break; } else if (AccessibilityHelpers.LastCredentials == null) { if (string.IsNullOrWhiteSpace(_lastNotificationUri)) { CancelOverlayPrompt(); break; } var uri = AccessibilityHelpers.GetUri(root); if (uri != null && uri != _lastNotificationUri) { CancelOverlayPrompt(); } else if (uri != null && uri.StartsWith(Constants.AndroidAppProtocol)) { CancelOverlayPrompt(); } break; } if (e.PackageName == BitwardenPackage) { CancelOverlayPrompt(); break; } if (ScanAndAutofill(root, e)) { CancelOverlayPrompt(); } break; default: break; } root.Dispose(); e.Dispose(); } // Suppress exceptions so that service doesn't crash. catch (Exception ex) { System.Diagnostics.Debug.WriteLine(">>> Exception: " + ex.StackTrace); } }
private void OverlayPromptToAutofill(AccessibilityNodeInfo root, AccessibilityEvent e) { if (Java.Lang.JavaSystem.CurrentTimeMillis() - _lastAutoFillTime < 1000 || AccessibilityHelpers.IsAutofillServicePromptVisible(Windows)) { return; } if (!AccessibilityHelpers.OverlayPermitted()) { if (!AccessibilityHelpers.IsAutofillTileAdded) { // The user has the option of only using the autofill tile and leaving the overlay permission // disabled, so only show this toast if they're using accessibility without overlay permission and // have _not_ added the autofill tile System.Diagnostics.Debug.WriteLine(">>> Overlay Permission not granted"); Toast.MakeText(this, AppResources.AccessibilityOverlayPermissionAlert, ToastLength.Long).Show(); } return; } if (_overlayView != null || _anchorNode != null || _overlayAnchorObserverRunning) { CancelOverlayPrompt(); } var uri = AccessibilityHelpers.GetUri(root); var fillable = !string.IsNullOrWhiteSpace(uri); if (fillable) { if (_blacklistedUris != null && _blacklistedUris.Any()) { if (Uri.TryCreate(uri, UriKind.Absolute, out var parsedUri) && parsedUri.Scheme.StartsWith("http")) { fillable = !_blacklistedUris.Contains( string.Format("{0}://{1}", parsedUri.Scheme, parsedUri.Host)); } else { fillable = !_blacklistedUris.Contains(uri); } } } if (!fillable) { return; } var intent = new Intent(this, typeof(AccessibilityActivity)); intent.PutExtra("uri", uri); intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop); _overlayView = AccessibilityHelpers.GetOverlayView(this); _overlayView.Measure(View.MeasureSpec.MakeMeasureSpec(0, 0), View.MeasureSpec.MakeMeasureSpec(0, 0)); _overlayViewHeight = _overlayView.MeasuredHeight; _overlayView.Click += (sender, eventArgs) => { CancelOverlayPrompt(); StartActivity(intent); }; var layoutParams = AccessibilityHelpers.GetOverlayLayoutParams(); var anchorPosition = AccessibilityHelpers.GetOverlayAnchorPosition(this, e.Source, _overlayViewHeight, _isOverlayAboveAnchor); layoutParams.X = anchorPosition.X; layoutParams.Y = anchorPosition.Y; if (_windowManager == null) { _windowManager = GetSystemService(WindowService).JavaCast <IWindowManager>(); } _anchorNode = e.Source; _lastAnchorX = anchorPosition.X; _lastAnchorY = anchorPosition.Y; _windowManager.AddView(_overlayView, layoutParams); System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Added at X:{0} Y:{1}", layoutParams.X, layoutParams.Y); StartOverlayAnchorObserver(); }
public override void OnAccessibilityEvent(AccessibilityEvent e) { try { var powerManager = GetSystemService(PowerService) as PowerManager; if (Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch && !powerManager.IsInteractive) { return; } else if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop && !powerManager.IsScreenOn) { return; } if (SkipPackage(e?.PackageName)) { return; } var root = RootInActiveWindow; if (root == null || root.PackageName != e.PackageName) { return; } // AccessibilityHelpers.PrintTestData(root, e); LoadServices(); var settingsTask = LoadSettingsAsync(); var notificationManager = GetSystemService(NotificationService) as NotificationManager; var cancelNotification = true; switch (e.EventType) { case EventTypes.ViewFocused: if (e.Source == null || !e.Source.Password || !_settingAutofillPasswordField) { break; } if (e.PackageName == BitwardenPackage) { CancelNotification(notificationManager); break; } if (ScanAndAutofill(root, e, notificationManager, cancelNotification)) { CancelNotification(notificationManager); } break; case EventTypes.WindowContentChanged: case EventTypes.WindowStateChanged: if (_settingAutofillPasswordField && e.Source.Password) { break; } else if (_settingAutofillPasswordField && AccessibilityHelpers.LastCredentials == null) { if (string.IsNullOrWhiteSpace(_lastNotificationUri)) { CancelNotification(notificationManager); break; } var uri = AccessibilityHelpers.GetUri(root); if (uri != _lastNotificationUri) { CancelNotification(notificationManager); } else if (uri.StartsWith(Constants.AndroidAppProtocol)) { CancelNotification(notificationManager, 30000); } break; } if (e.PackageName == BitwardenPackage) { CancelNotification(notificationManager); break; } if (_settingAutofillPersistNotification) { var uri = AccessibilityHelpers.GetUri(root); if (uri != null && !uri.Contains(BitwardenWebsite)) { var needToFill = AccessibilityHelpers.NeedToAutofill( AccessibilityHelpers.LastCredentials, uri); if (needToFill) { var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false); needToFill = passwordNodes.Any(); if (needToFill) { AccessibilityHelpers.GetNodesAndFill(root, e, passwordNodes); } passwordNodes.Dispose(); } if (!needToFill) { NotifyToAutofill(uri, notificationManager); cancelNotification = false; } } AccessibilityHelpers.LastCredentials = null; } else { cancelNotification = ScanAndAutofill(root, e, notificationManager, cancelNotification); } if (cancelNotification) { CancelNotification(notificationManager); } break; default: break; } notificationManager?.Dispose(); root.Dispose(); e.Dispose(); } // Suppress exceptions so that service doesn't crash. catch { } }
private void OverlayPromptToAutofill(AccessibilityNodeInfo root, AccessibilityEvent e) { if (!AccessibilityHelpers.OverlayPermitted()) { System.Diagnostics.Debug.WriteLine(">>> Overlay Permission not granted"); Toast.MakeText(this, AppResources.AccessibilityOverlayPermissionAlert, ToastLength.Long).Show(); return; } var uri = AccessibilityHelpers.GetUri(root); if (string.IsNullOrWhiteSpace(uri)) { return; } WindowManagerTypes windowManagerType; if (Build.VERSION.SdkInt >= BuildVersionCodes.O) { windowManagerType = WindowManagerTypes.ApplicationOverlay; } else { windowManagerType = WindowManagerTypes.Phone; } var layoutParams = new WindowManagerLayoutParams( ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent, windowManagerType, WindowManagerFlags.NotFocusable | WindowManagerFlags.NotTouchModal, Format.Transparent); var anchorPosition = AccessibilityHelpers.GetOverlayAnchorPosition(root, e); layoutParams.Gravity = GravityFlags.Bottom | GravityFlags.Left; layoutParams.X = anchorPosition.X; layoutParams.Y = anchorPosition.Y; var intent = new Intent(this, typeof(AccessibilityActivity)); intent.PutExtra("uri", uri); intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop); if (_windowManager == null) { _windowManager = GetSystemService(WindowService).JavaCast <IWindowManager>(); } var updateView = false; if (_overlayView != null) { updateView = true; } _overlayView = AccessibilityHelpers.GetOverlayView(this); _overlayView.Click += (sender, eventArgs) => { CancelOverlayPrompt(); StartActivity(intent); }; _lastNotificationUri = uri; if (updateView) { _windowManager.UpdateViewLayout(_overlayView, layoutParams); } else { _windowManager.AddView(_overlayView, layoutParams); } System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View {0} X:{1} Y:{2}", updateView ? "Updated to" : "Added at", layoutParams.X, layoutParams.Y); }