From 237b1030c7f847db812b80b81fa1508a1fa60aaa Mon Sep 17 00:00:00 2001 From: Ionut Cristian Bedregeanu Date: Mon, 4 Oct 2021 11:45:22 +0300 Subject: [PATCH] For #5509 - Show the toolbar and floating buttons when a11y services are enabled --- .../mozilla/focus/browser/DisplayToolbar.kt | 18 ++++++++++- .../java/org/mozilla/focus/utils/Settings.kt | 30 ++++++++++++++++++- .../widget/FloatingActionButtonBehavior.java | 4 ++- .../focus/widget/FloatingEraseButton.java | 9 +----- .../focus/widget/FloatingSessionsButton.java | 8 +---- 5 files changed, 51 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/mozilla/focus/browser/DisplayToolbar.kt b/app/src/main/java/org/mozilla/focus/browser/DisplayToolbar.kt index dea7b976016..9d447db39a5 100644 --- a/app/src/main/java/org/mozilla/focus/browser/DisplayToolbar.kt +++ b/app/src/main/java/org/mozilla/focus/browser/DisplayToolbar.kt @@ -7,7 +7,12 @@ package org.mozilla.focus.browser import android.content.Context import android.util.AttributeSet import com.google.android.material.appbar.AppBarLayout -import kotlinx.android.synthetic.main.browser_display_toolbar.view.* +import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS +import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL +import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP +import kotlinx.android.synthetic.main.browser_display_toolbar.view.browserToolbar +import kotlinx.android.synthetic.main.browser_display_toolbar.view.urlbar +import org.mozilla.focus.utils.Settings /** * The toolbar of the BrowserFragment; displaying the URL and other controls. @@ -16,12 +21,23 @@ class DisplayToolbar( context: Context, attrs: AttributeSet ) : AppBarLayout(context, attrs), AppBarLayout.OnOffsetChangedListener { + init { addOnOffsetChangedListener(this) } @Suppress("MagicNumber") // A mathematical expression - No need to add constants for 100% and 50%. override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) { + + if (Settings.getInstance(context).isAccessibilityEnabled()) { + (urlbar.layoutParams as LayoutParams).scrollFlags = LayoutParams.SCROLL_FLAG_NO_SCROLL + browserToolbar.alpha = 1f + return + } else { + (urlbar.layoutParams as LayoutParams).scrollFlags = + SCROLL_FLAG_SCROLL or SCROLL_FLAG_ENTER_ALWAYS or SCROLL_FLAG_SNAP + } + // When scrolling the toolbar away we want to fade out the content on the toolbar // with an alpha animation. This will avoid that the text clashes with the status bar. diff --git a/app/src/main/java/org/mozilla/focus/utils/Settings.kt b/app/src/main/java/org/mozilla/focus/utils/Settings.kt index 453d3aef424..38e5d894f7e 100644 --- a/app/src/main/java/org/mozilla/focus/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/focus/utils/Settings.kt @@ -4,9 +4,11 @@ package org.mozilla.focus.utils +import android.accessibilityservice.AccessibilityServiceInfo import android.content.Context import android.content.SharedPreferences import android.content.res.Resources +import android.view.accessibility.AccessibilityManager import androidx.preference.PreferenceManager import mozilla.components.concept.engine.Engine import mozilla.components.concept.engine.EngineSession @@ -18,7 +20,7 @@ import org.mozilla.focus.searchsuggestions.SearchSuggestionsPreferences /** * A simple wrapper for SharedPreferences that makes reading preference a little bit easier. */ -@Suppress("TooManyFunctions") // This class is designed to have a lot of (simple) functions +@Suppress("TooManyFunctions", "LargeClass") // This class is designed to have a lot of (simple) functions class Settings private constructor( private val context: Context ) { @@ -35,6 +37,26 @@ class Settings private constructor( } } + private val accessibilityManager = + context.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager? + + /** + * Check each active accessibility service to see if it can perform gestures, if any can, + * then it is *likely* a switch service is enabled. + */ + private val switchServiceIsEnabled: Boolean + get() { + accessibilityManager?.getEnabledAccessibilityServiceList(0)?.let { activeServices -> + for (service in activeServices) { + if (service.capabilities.and(AccessibilityServiceInfo.CAPABILITY_CAN_PERFORM_GESTURES) == 1) { + return true + } + } + } + + return false + } + private val preferencesListener = EngineSharedPreferencesListener(context) private val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context).apply { @@ -210,6 +232,12 @@ class Settings private constructor( false ) + /** + * This is automatically inferred based on the current system status. Not a setting in our app. + */ + fun isAccessibilityEnabled() = + accessibilityManager?.isTouchExplorationEnabled ?: false || switchServiceIsEnabled + fun userHasToggledSearchSuggestions(): Boolean = preferences.getBoolean(SearchSuggestionsPreferences.TOGGLED_SUGGESTIONS_PREF, false) diff --git a/app/src/main/java/org/mozilla/focus/widget/FloatingActionButtonBehavior.java b/app/src/main/java/org/mozilla/focus/widget/FloatingActionButtonBehavior.java index 016a0f48fd9..b8f867ec9f9 100644 --- a/app/src/main/java/org/mozilla/focus/widget/FloatingActionButtonBehavior.java +++ b/app/src/main/java/org/mozilla/focus/widget/FloatingActionButtonBehavior.java @@ -14,6 +14,8 @@ import android.util.AttributeSet; import android.view.View; +import org.mozilla.focus.utils.Settings; + /** * A Behavior implementation that will hide/show a FloatingActionButton based on whether an AppBarLayout * is visible or not. @@ -58,7 +60,7 @@ public void onDependentViewRemoved(CoordinatorLayout parent, FloatingActionButto @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { - if (verticalOffset == 0 && !visible) { + if ((verticalOffset == 0 && !visible) || Settings.getInstance(appBarLayout.getContext()).isAccessibilityEnabled()) { showButton(); } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange() && visible) { hideButton(); diff --git a/app/src/main/java/org/mozilla/focus/widget/FloatingEraseButton.java b/app/src/main/java/org/mozilla/focus/widget/FloatingEraseButton.java index 7a0c0881009..e080923504a 100644 --- a/app/src/main/java/org/mozilla/focus/widget/FloatingEraseButton.java +++ b/app/src/main/java/org/mozilla/focus/widget/FloatingEraseButton.java @@ -9,7 +9,6 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton; import android.util.AttributeSet; import android.view.View; -import android.view.accessibility.AccessibilityManager; import android.view.animation.AnimationUtils; import org.mozilla.focus.R; @@ -32,17 +31,11 @@ public FloatingEraseButton(Context context, AttributeSet attrs, int defStyleAttr public void updateSessionsCount(int tabCount) { final CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) getLayoutParams(); final FloatingActionButtonBehavior behavior = (FloatingActionButtonBehavior) params.getBehavior(); - AccessibilityManager accessibilityManager = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); keepHidden = tabCount != 1; if (behavior != null) { - if (accessibilityManager != null && accessibilityManager.isTouchExplorationEnabled()) { - // Always display erase button if Talk Back is enabled - behavior.setAutoHideEnabled(false); - } else { - behavior.setAutoHideEnabled(!keepHidden); - } + behavior.setAutoHideEnabled(!keepHidden); } if (keepHidden) { diff --git a/app/src/main/java/org/mozilla/focus/widget/FloatingSessionsButton.java b/app/src/main/java/org/mozilla/focus/widget/FloatingSessionsButton.java index 4d4d900374d..52e53b25b96 100644 --- a/app/src/main/java/org/mozilla/focus/widget/FloatingSessionsButton.java +++ b/app/src/main/java/org/mozilla/focus/widget/FloatingSessionsButton.java @@ -70,13 +70,7 @@ public void updateSessionsCount(int tabCount) { if (behavior != null) { behavior.setAutoHideEnabled(shouldBeVisible); } - - if (shouldBeVisible) { - show(); - invalidate(); - } else { - hide(); - } + invalidate(); } }