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

Commit f04786ea authored by mincheli's avatar mincheli Committed by Minche Li
Browse files

Waits for windowMagnification connection set when requesting enableWindowMagnification

It fixes the low quality CTS test, AccessibilityMagnificationTest.
And this fix also makes enableWindowMagnification() a robust API
that can be called frequently when the connection is toggled.

CL comments and discussion are at ag/16785609

Root cause:
1. when the test cases run iteratively, the test a11y service would be
enabled and disabled repeatedly so the windowMagnification
connection would also be connected and disconnected repeatedly.
And when the test a11y service is enabled in a short time, the
connection may not be ready to be established.

Solution:
1. So we add a wait lock and notify to unclock after the connection
is established. And prevent the duplicated connection request.

Bug: 2147470987
Test: atest AccessibilityMagnificationTest --iterations,
    atest com.android.server.accessibility
Change-Id: I6ec22e66796aaf565c10b0fedcd4de359ce5fc7b
parent fba11335
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2749,6 +2749,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
    }

    private void updateWindowMagnificationConnectionIfNeeded(AccessibilityUserState userState) {
        if (!mMagnificationController.supportWindowMagnification()) {
            return;
        }
        final boolean connect = (userState.isShortcutMagnificationEnabledLocked()
                || userState.isDisplayMagnificationEnabledLocked())
                && (userState.getMagnificationCapabilitiesLocked()
+10 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.accessibility.magnification;

import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_WINDOW;
import static android.content.pm.PackageManager.FEATURE_WINDOW_MAGNIFICATION;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
@@ -91,6 +92,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
    private FullScreenMagnificationController mFullScreenMagnificationController;
    private WindowMagnificationManager mWindowMagnificationMgr;
    private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
    /** Whether the platform supports window magnification feature. */
    private final boolean mSupportWindowMagnification;

    @GuardedBy("mLock")
    private int mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
@@ -129,6 +132,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
        mScaleProvider = scaleProvider;
        LocalServices.getService(WindowManagerInternal.class)
                .getAccessibilityController().setUiChangesForAccessibilityCallbacks(this);
        mSupportWindowMagnification = context.getPackageManager().hasSystemFeature(
                FEATURE_WINDOW_MAGNIFICATION);
    }

    @VisibleForTesting
@@ -185,6 +190,11 @@ public class MagnificationController implements WindowMagnificationManager.Callb
        }
    }

    /** Returns {@code true} if the platform supports window magnification feature. */
    public boolean supportWindowMagnification() {
        return mSupportWindowMagnification;
    }

    /**
     * Transitions to the target Magnification mode with current center of the magnification mode
     * if it is available.
+4 −0
Original line number Diff line number Diff line
@@ -396,6 +396,10 @@ public class MagnificationProcessor {

            dumpTrackingTypingFocusEnabledState(pw, displayId, config.getMode());
        }
        pw.append("    SupportWindowMagnification="
                + mController.supportWindowMagnification()).println();
        pw.append("    WindowMagnificationConnectionState="
                + mController.getWindowMagnificationMgr().getConnectionState()).println();
    }

    private int getIdOfLastServiceToMagnify(int mode, int displayId) {
+90 −9
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.graphics.Region;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Slog;
import android.util.SparseArray;
import android.view.MotionEvent;
@@ -87,6 +88,30 @@ public class WindowMagnificationManager implements
    })
    public @interface WindowPosition {}

    /** Window magnification connection is connecting. */
    private static final int CONNECTING = 0;
    /** Window magnification connection is connected. */
    private static final int CONNECTED = 1;
    /** Window magnification connection is disconnecting. */
    private static final int DISCONNECTING = 2;
    /** Window magnification connection is disconnected. */
    private static final int DISCONNECTED = 3;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"CONNECTION_STATE"}, value = {
            CONNECTING,
            CONNECTED,
            DISCONNECTING,
            DISCONNECTED
    })
    private @interface ConnectionState {
    }

    @ConnectionState
    private int mConnectionState = DISCONNECTED;

    private static final int WAIT_CONNECTION_TIMEOUT_MILLIS = 100;

    private final Object mLock;
    private final Context mContext;
    @VisibleForTesting
@@ -178,7 +203,7 @@ public class WindowMagnificationManager implements
     */
    public void setConnection(@Nullable IWindowMagnificationConnection connection) {
        if (DBG) {
            Slog.d(TAG, "setConnection :" + connection);
            Slog.d(TAG, "setConnection :" + connection + " ,mConnectionState=" + mConnectionState);
        }
        synchronized (mLock) {
            // Reset connectionWrapper.
@@ -189,6 +214,13 @@ public class WindowMagnificationManager implements
                }
                mConnectionWrapper.unlinkToDeath(mConnectionCallback);
                mConnectionWrapper = null;
                // The connection is still connecting so it is no need to reset the
                // connection state to disconnected.
                // TODO b/220086369 will reset the connection immediately when requestConnection
                //  is called
                if (mConnectionState != CONNECTING) {
                    setConnectionState(DISCONNECTED);
                }
            }
            if (connection != null) {
                mConnectionWrapper = new WindowMagnificationConnectionWrapper(connection, mTrace);
@@ -199,9 +231,13 @@ public class WindowMagnificationManager implements
                    mConnectionCallback = new ConnectionCallback();
                    mConnectionWrapper.linkToDeath(mConnectionCallback);
                    mConnectionWrapper.setConnectionCallback(mConnectionCallback);
                    setConnectionState(CONNECTED);
                } catch (RemoteException e) {
                    Slog.e(TAG, "setConnection failed", e);
                    mConnectionWrapper = null;
                    setConnectionState(DISCONNECTED);
                } finally {
                    mLock.notify();
                }
            }
        }
@@ -229,10 +265,20 @@ public class WindowMagnificationManager implements
        if (DBG) {
            Slog.d(TAG, "requestConnection :" + connect);
        }
        if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
            mTrace.logTrace(TAG + ".requestWindowMagnificationConnection",
                    FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "connect=" + connect);
        }
        synchronized (mLock) {
            if (connect == isConnected()) {
            if ((connect && (mConnectionState == CONNECTED || mConnectionState == CONNECTING))
                    || (!connect && (mConnectionState == DISCONNECTED
                    || mConnectionState == DISCONNECTING))) {
                Slog.w(TAG,
                        "requestConnection duplicated request: connect=" + connect
                                + " ,mConnectionState=" + mConnectionState);
                return false;
            }

            if (connect) {
                final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
                if (!mReceiverRegistered) {
@@ -247,19 +293,42 @@ public class WindowMagnificationManager implements
                }
            }
        }
        if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
            mTrace.logTrace(TAG + ".requestWindowMagnificationConnection",
                    FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "connect=" + connect);
        if (requestConnectionInternal(connect)) {
            setConnectionState(connect ? CONNECTING : DISCONNECTING);
            return true;
        } else {
            setConnectionState(DISCONNECTED);
            return false;
        }
    }

    private boolean requestConnectionInternal(boolean connect) {
        final long identity = Binder.clearCallingIdentity();
        try {
            final StatusBarManagerInternal service = LocalServices.getService(
                    StatusBarManagerInternal.class);
            service.requestWindowMagnificationConnection(connect);
            if (service != null) {
                return service.requestWindowMagnificationConnection(connect);
            }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
        return true;
        return false;
    }

    /**
     * Returns window magnification connection state.
     */
    public int getConnectionState() {
        return mConnectionState;
    }

    private void setConnectionState(@ConnectionState int state) {
        if (DBG) {
            Slog.d(TAG, "setConnectionState : state=" + state + " ,mConnectionState="
                    + mConnectionState);
        }
        mConnectionState = state;
    }

    /**
@@ -849,6 +918,7 @@ public class WindowMagnificationManager implements
                mConnectionWrapper.unlinkToDeath(this);
                mConnectionWrapper = null;
                mConnectionCallback = null;
                setConnectionState(DISCONNECTED);
                resetWindowMagnifiers();
            }
        }
@@ -1025,8 +1095,19 @@ public class WindowMagnificationManager implements
            float centerY, float magnificationFrameOffsetRatioX,
            float magnificationFrameOffsetRatioY,
            MagnificationAnimationCallback animationCallback) {
        // Wait for the connection with a timeout.
        final long endMillis = SystemClock.uptimeMillis() + WAIT_CONNECTION_TIMEOUT_MILLIS;
        while (mConnectionState == CONNECTING && (SystemClock.uptimeMillis() < endMillis)) {
            try {
                mLock.wait(endMillis - SystemClock.uptimeMillis());
            } catch (InterruptedException ie) {
                /* ignore */
            }
        }
        if (mConnectionWrapper == null) {
            Slog.w(TAG, "enableWindowMagnificationInternal mConnectionWrapper is null");
            Slog.w(TAG,
                    "enableWindowMagnificationInternal mConnectionWrapper is null. "
                            + "mConnectionState=" + mConnectionState);
            return false;
        }
        return mConnectionWrapper.enableWindowMagnification(
+1 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ public interface StatusBarManagerInternal {
     * @see com.android.internal.statusbar.IStatusBar#requestWindowMagnificationConnection(boolean
     * request)
     */
    void requestWindowMagnificationConnection(boolean request);
    boolean requestWindowMagnificationConnection(boolean request);

    /**
     * Handles a logging command from the WM shell command.
Loading