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

Commit 4445345f authored by Rhed Jao's avatar Rhed Jao Committed by Android (Google) Code Review
Browse files

Merge "Update VolumeDialog to use a11y api for ui timeout value."

parents edc06c8c 4684223a
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -14,14 +14,11 @@

package com.android.systemui.statusbar.policy;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;

import java.util.List;

/**
 * For mocking because AccessibilityManager is final for some reason...
 */
@@ -62,8 +59,8 @@ public class AccessibilityManagerWrapper implements
        mAccessibilityManager.sendAccessibilityEvent(event);
    }

    public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
            int feedbackTypeFlags) {
        return mAccessibilityManager.getEnabledAccessibilityServiceList(feedbackTypeFlags);
    /** Returns a recommended ui timeout value in milliseconds. */
    public int getRecommendedTimeoutMillis(int originalTimeout, int uiContentFlags) {
        return mAccessibilityManager.getRecommendedTimeoutMillis(originalTimeout, uiContentFlags);
    }
}
+17 −51
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.systemui.volume;

import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.media.AudioManager.RINGER_MODE_NORMAL;
import static android.media.AudioManager.RINGER_MODE_SILENT;
@@ -32,7 +30,6 @@ import static android.view.View.VISIBLE;

import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
@@ -68,13 +65,12 @@ import android.view.ContextThemeWrapper;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
@@ -113,6 +109,10 @@ public class VolumeDialogImpl implements VolumeDialog {
    private static final long USER_ATTEMPT_GRACE_PERIOD = 1000;
    private static final int UPDATE_ANIMATION_DURATION = 80;

    static final int DIALOG_TIMEOUT_MILLIS = 3000;
    static final int DIALOG_SAFETYWARNING_TIMEOUT_MILLIS = 5000;
    static final int DIALOG_HOVERING_TIMEOUT_MILLIS = 16000;

    private final Context mContext;
    private final H mHandler = new H();
    private final VolumeDialogController mController;
@@ -170,7 +170,6 @@ public class VolumeDialogImpl implements VolumeDialog {

    @Override
    public void destroy() {
        mAccessibility.destroy();
        mController.removeCallback(mControllerCallbackH);
        mHandler.removeCallbacksAndMessages(null);
    }
@@ -356,8 +355,6 @@ public class VolumeDialogImpl implements VolumeDialog {
        writer.print("  mDynamic: "); writer.println(mDynamic);
        writer.print("  mAutomute: "); writer.println(mAutomute);
        writer.print("  mSilentMode: "); writer.println(mSilentMode);
        writer.print("  mAccessibility.mFeedbackEnabled: ");
        writer.println(mAccessibility.mFeedbackEnabled);
    }

    private static int getImpliedLevel(SeekBar seekBar, int progress) {
@@ -571,10 +568,18 @@ public class VolumeDialogImpl implements VolumeDialog {
    }

    private int computeTimeoutH() {
        if (mAccessibility.mFeedbackEnabled) return 20000;
        if (mHovering) return 16000;
        if (mSafetyWarning != null) return 5000;
        return 3000;
        if (mHovering) {
            return mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_HOVERING_TIMEOUT_MILLIS,
                    AccessibilityManager.FLAG_CONTENT_CONTROLS);
        }
        if (mSafetyWarning != null) {
            return mAccessibilityMgr.getRecommendedTimeoutMillis(
                    DIALOG_SAFETYWARNING_TIMEOUT_MILLIS,
                    AccessibilityManager.FLAG_CONTENT_TEXT
                            | AccessibilityManager.FLAG_CONTENT_CONTROLS);
        }
        return mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_TIMEOUT_MILLIS,
                AccessibilityManager.FLAG_CONTENT_CONTROLS);
    }

    protected void dismissH(int reason) {
@@ -1261,28 +1266,8 @@ public class VolumeDialogImpl implements VolumeDialog {
    }

    private final class Accessibility extends AccessibilityDelegate {
        private boolean mFeedbackEnabled;

        public void init() {
            mDialogView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
                @Override
                public void onViewDetachedFromWindow(View v) {
                    if (D.BUG) Log.d(TAG, "onViewDetachedFromWindow");
                }

                @Override
                public void onViewAttachedToWindow(View v) {
                    if (D.BUG) Log.d(TAG, "onViewAttachedToWindow");
                    updateFeedbackEnabled();
                }
            });
            mDialogView.setAccessibilityDelegate(this);
            mAccessibilityMgr.addCallback(mListener);
            updateFeedbackEnabled();
        }

        public void destroy() {
            mAccessibilityMgr.removeCallback(mListener);
        }

        @Override
@@ -1298,25 +1283,6 @@ public class VolumeDialogImpl implements VolumeDialog {
            rescheduleTimeoutH();
            return super.onRequestSendAccessibilityEvent(host, child, event);
        }

        private void updateFeedbackEnabled() {
            mFeedbackEnabled = computeFeedbackEnabled();
        }

        private boolean computeFeedbackEnabled() {
            // are there any enabled non-generic a11y services?
            final List<AccessibilityServiceInfo> services =
                    mAccessibilityMgr.getEnabledAccessibilityServiceList(FEEDBACK_ALL_MASK);
            for (AccessibilityServiceInfo asi : services) {
                if (asi.feedbackType != 0 && asi.feedbackType != FEEDBACK_GENERIC) {
                    return true;
                }
            }
            return false;
        }

        private final AccessibilityServicesStateChangeListener mListener =
                enabled -> updateFeedbackEnabled();
    }

    private static class VolumeRow {
+46 −2
Original line number Diff line number Diff line
@@ -27,18 +27,23 @@ import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS;

import static junit.framework.Assert.assertTrue;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.KeyguardManager;
import android.media.AudioManager;
import android.os.SystemClock;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.text.TextUtils;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.widget.ImageView;

import com.android.systemui.R;
@@ -48,10 +53,11 @@ import com.android.systemui.plugins.VolumeDialogController.State;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import java.util.function.Predicate;
@@ -59,7 +65,6 @@ import java.util.function.Predicate;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@Ignore
public class VolumeDialogImplTest extends SysuiTestCase {

    VolumeDialogImpl mDialog;
@@ -113,6 +118,45 @@ public class VolumeDialogImplTest extends SysuiTestCase {
                    + " failed test", condition.test(view));
        }
    }

    @Test
    public void testComputeTimeout() {
        Mockito.reset(mAccessibilityMgr);
        mDialog.rescheduleTimeoutH();
        verify(mAccessibilityMgr).getRecommendedTimeoutMillis(
                VolumeDialogImpl.DIALOG_TIMEOUT_MILLIS,
                AccessibilityManager.FLAG_CONTENT_CONTROLS);
    }

    @Test
    public void testComputeTimeout_withHovering() {
        Mockito.reset(mAccessibilityMgr);
        View dialog = mDialog.getDialogView();
        long uptimeMillis = SystemClock.uptimeMillis();
        MotionEvent event = MotionEvent.obtain(uptimeMillis, uptimeMillis,
                MotionEvent.ACTION_HOVER_ENTER, 0, 0, 0);
        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
        dialog.dispatchGenericMotionEvent(event);
        event.recycle();
        verify(mAccessibilityMgr).getRecommendedTimeoutMillis(
                VolumeDialogImpl.DIALOG_HOVERING_TIMEOUT_MILLIS,
                AccessibilityManager.FLAG_CONTENT_CONTROLS);
    }

    @Test
    public void testComputeTimeout_withSafetyWarningOn() {
        Mockito.reset(mAccessibilityMgr);
        ArgumentCaptor<VolumeDialogController.Callbacks> controllerCallbackCapture =
                ArgumentCaptor.forClass(VolumeDialogController.Callbacks.class);
        verify(mController).addCallback(controllerCallbackCapture.capture(), any());
        VolumeDialogController.Callbacks callbacks = controllerCallbackCapture.getValue();
        callbacks.onShowSafetyWarning(AudioManager.FLAG_SHOW_UI);
        verify(mAccessibilityMgr).getRecommendedTimeoutMillis(
                VolumeDialogImpl.DIALOG_SAFETYWARNING_TIMEOUT_MILLIS,
                AccessibilityManager.FLAG_CONTENT_TEXT
                        | AccessibilityManager.FLAG_CONTENT_CONTROLS);
    }

/*
    @Test
    public void testContentDescriptions() {