Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9474bb6 authored by Isaac Chai's avatar Isaac Chai
Browse files

settings no hiding when voiceaccess or switchaccess is on

Test: Locally tested and also added unit tests MagnificationModeSwitchTest
Bug: 288979372

Change-Id: I9a8e557b6748ef5b4bb89e375f78954734aa4d30
parent 116560a4
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -977,4 +977,13 @@
    Width in pixels of the Side FPS sensor.
    -->
    <integer name="config_sfpsSensorWidth">200</integer>

    <!--
    They are service names that, if enabled, will cause the magnification settings button
    to never hide after timeout.
    -->
    <string-array name="services_always_show_magnification_settings" translatable="false">
        <item>com.android.switchaccess.SwitchAccessService</item>
        <item>com.google.android.apps.accessibility.voiceaccess.JustSpeakService</item>
    </string-array>
</resources>
+41 −1
Original line number Diff line number Diff line
@@ -20,12 +20,14 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.NonNull;
import android.annotation.UiContext;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Rect;
@@ -49,6 +51,8 @@ import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.systemui.res.R;

import java.util.Collections;
import java.util.Optional;
import java.util.Set;

/**
 * Shows/hides a {@link android.widget.ImageView} on the screen and changes the values of
@@ -315,11 +319,47 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
                    DEFAULT_FADE_OUT_ANIMATION_DELAY_MS,
                    AccessibilityManager.FLAG_CONTENT_ICONS
                            | AccessibilityManager.FLAG_CONTENT_CONTROLS);
            if (shouldAlwaysShowSettings()) {
                mUiTimeout = -1;
            }
        }
        // Refresh the time slot of the fade-out task whenever this method is called.
        stopFadeOutAnimation();
        if (mUiTimeout >= 0) {
            mImageView.postOnAnimationDelayed(mFadeOutAnimationTask, mUiTimeout);
        }
    }

    private boolean shouldAlwaysShowSettings() {
        try {
            var serviceNamesArray = mContext.getResources().getStringArray(
                    R.array.services_always_show_magnification_settings);
            if (serviceNamesArray.length == 0) {
                return false;
            }
            Set serviceNamesSet = Set.of(serviceNamesArray);

            var serviceInfoList = mAccessibilityManager
                    .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
            for (var serviceInfo : serviceInfoList) {
                var serviceName = Optional.ofNullable(serviceInfo)
                        .map(AccessibilityServiceInfo::getResolveInfo)
                        .map(resolveInfo -> resolveInfo.serviceInfo)
                        .map(resolvedServiceInfo -> resolvedServiceInfo.name)
                        .orElse(null);
                if (serviceName == null) {
                    continue;
                }

                if (serviceNamesSet.contains(serviceName)) {
                    return true;
                }
            }
        } catch (Resources.NotFoundException nfe) {
            // No-op. Do not crash for not finding resources.
        }
        return false;
    }

    private void stopFadeOutAnimation() {
        mImageView.removeCallbacks(mFadeOutAnimationTask);
+85 −1
Original line number Diff line number Diff line
@@ -49,8 +49,11 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Handler;
@@ -71,8 +74,8 @@ import android.widget.ImageView;
import androidx.test.filters.SmallTest;

import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.res.R;

import org.junit.After;
import org.junit.Before;
@@ -185,6 +188,87 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
        verify(mSpyImageView).postOnAnimationDelayed(any(Runnable.class), eq((long) a11yTimeout));
    }

    @Test
    public void showMagnificationButton_noA11yServicesRunning_postDelayedAnimationsWithTimeout() {
        final int a11yTimeout = 12345;
        when(mAccessibilityManager.getRecommendedTimeoutMillis(anyInt(), anyInt())).thenReturn(
                a11yTimeout);
        when(mAccessibilityManager.getEnabledAccessibilityServiceList(anyInt()))
                .thenReturn(List.of());

        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);

        verify(mAccessibilityManager).getRecommendedTimeoutMillis(
                DEFAULT_FADE_OUT_ANIMATION_DELAY_MS, AccessibilityManager.FLAG_CONTENT_ICONS
                        | AccessibilityManager.FLAG_CONTENT_CONTROLS);
        verify(mSpyImageView).postOnAnimationDelayed(any(Runnable.class), eq((long) a11yTimeout));
    }

    @Test
    public void showMagnificationButton_voiceAccessRunning_noTimeout() {
        var serviceInfo = createServiceInfoWithName(
                "com.google.android.apps.accessibility.voiceaccess.JustSpeakService");
        when(mAccessibilityManager.getEnabledAccessibilityServiceList(anyInt()))
                .thenReturn(List.of(serviceInfo));

        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);

        verify(mSpyImageView, never()).postOnAnimationDelayed(any(Runnable.class), anyLong());
    }

    @Test
    public void showMagnificationButton_switchAccessRunning_noTimeout() {
        var serviceInfo = createServiceInfoWithName(
                "com.android.switchaccess.SwitchAccessService");
        when(mAccessibilityManager.getEnabledAccessibilityServiceList(anyInt()))
                .thenReturn(List.of(serviceInfo));

        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);

        verify(mSpyImageView, never()).postOnAnimationDelayed(any(Runnable.class), anyLong());
    }

    @Test
    public void showMagnificationButton_switchAccessAndVoiceAccessBothRunning_noTimeout() {
        var switchAccessServiceInfo = createServiceInfoWithName(
                "com.android.switchaccess.SwitchAccessService");
        var voiceAccessServiceInfo = createServiceInfoWithName(
                "com.google.android.apps.accessibility.voiceaccess.JustSpeakService");
        when(mAccessibilityManager.getEnabledAccessibilityServiceList(anyInt()))
                .thenReturn(List.of(switchAccessServiceInfo, voiceAccessServiceInfo));

        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);

        verify(mSpyImageView, never()).postOnAnimationDelayed(any(Runnable.class), anyLong());
    }

    @Test
    public void showMagnificationButton_someOtherServiceRunning_postDelayedAnimationsWithTimeout() {
        final int a11yTimeout = 12345;
        when(mAccessibilityManager.getRecommendedTimeoutMillis(anyInt(), anyInt())).thenReturn(
                a11yTimeout);
        var serviceInfo1 = createServiceInfoWithName("com.test.someService1");
        var serviceInfo2 = createServiceInfoWithName("com.test.someService2");
        when(mAccessibilityManager.getEnabledAccessibilityServiceList(anyInt()))
                .thenReturn(List.of(serviceInfo1, serviceInfo2));

        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);

        verify(mAccessibilityManager).getRecommendedTimeoutMillis(
                DEFAULT_FADE_OUT_ANIMATION_DELAY_MS, AccessibilityManager.FLAG_CONTENT_ICONS
                        | AccessibilityManager.FLAG_CONTENT_CONTROLS);
        verify(mSpyImageView).postOnAnimationDelayed(any(Runnable.class), eq((long) a11yTimeout));
    }

    private AccessibilityServiceInfo createServiceInfoWithName(String name) {
        var resolveInfo = new ResolveInfo();
        resolveInfo.serviceInfo = new ServiceInfo();
        resolveInfo.serviceInfo.name = name;
        var serviceInfo = new AccessibilityServiceInfo();
        serviceInfo.setResolveInfo(resolveInfo);
        return serviceInfo;
    }

    @Test
    public void showMagnificationButton_windowModeAndFadingOut_verifyAnimationEndAction() {
        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);