All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.view.RemoteAccessibilityController Maven / Gradle / Ivy

/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

import android.graphics.Matrix;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.accessibility.IAccessibilityEmbeddedConnection;

class RemoteAccessibilityController {
    private static final String TAG = "RemoteAccessibilityController";
    private int mHostId;
    private RemoteAccessibilityEmbeddedConnection mConnectionWrapper;
    private Matrix mScreenMatrixForEmbeddedHierarchy = new Matrix();
    private final float[] mMatrixValues = new float[9];
    private View mHostView;

    RemoteAccessibilityController(View v) {
        mHostView = v;
    }

    private void runOnUiThread(Runnable runnable) {
        final Handler h = mHostView.getHandler();
        if (h != null && h.getLooper() != Looper.myLooper()) {
            h.post(runnable);
        } else {
            runnable.run();
        }
    }

    void assosciateHierarchy(IAccessibilityEmbeddedConnection connection,
        IBinder leashToken, int hostId) {
        mHostId = hostId;

        try {
            leashToken = connection.associateEmbeddedHierarchy(
                leashToken, mHostId);
            setRemoteAccessibilityEmbeddedConnection(connection, leashToken);
        } catch (RemoteException e) {
            Log.d(TAG, "Error in associateEmbeddedHierarchy " + e);
        }
    }

    void disassosciateHierarchy() {
        setRemoteAccessibilityEmbeddedConnection(null, null);
    }

    boolean alreadyAssociated(IAccessibilityEmbeddedConnection connection) {
        if (mConnectionWrapper == null) {
            return false;
        }
        return mConnectionWrapper.mConnection.equals(connection);
    }

    boolean connected() {
      return mConnectionWrapper != null;
    }

    IBinder getLeashToken() {
        return mConnectionWrapper.getLeashToken();
    }

    /**
     * Wrapper of accessibility embedded connection for embedded view hierarchy.
     */
    private final class RemoteAccessibilityEmbeddedConnection implements IBinder.DeathRecipient {
        private final IAccessibilityEmbeddedConnection mConnection;
        private final IBinder mLeashToken;

        RemoteAccessibilityEmbeddedConnection(IAccessibilityEmbeddedConnection connection,
                IBinder leashToken) {
            mConnection = connection;
            mLeashToken = leashToken;
        }

        IAccessibilityEmbeddedConnection getConnection() {
            return mConnection;
        }

        IBinder getLeashToken() {
            return mLeashToken;
        }

        void linkToDeath() throws RemoteException {
            mConnection.asBinder().linkToDeath(this, 0);
        }

        void unlinkToDeath() {
            mConnection.asBinder().unlinkToDeath(this, 0);
        }

        @Override
        public void binderDied() {
            unlinkToDeath();
            runOnUiThread(() -> {
                if (mConnectionWrapper == this) {
                    mConnectionWrapper = null;
                }
            });
        }
    }

    private void setRemoteAccessibilityEmbeddedConnection(
          IAccessibilityEmbeddedConnection connection, IBinder leashToken) {
        try {
            if (mConnectionWrapper != null) {
                mConnectionWrapper.getConnection()
                    .disassociateEmbeddedHierarchy();
                mConnectionWrapper.unlinkToDeath();
                mConnectionWrapper = null;
            }
            if (connection != null && leashToken != null) {
                mConnectionWrapper =
                    new RemoteAccessibilityEmbeddedConnection(connection, leashToken);
                mConnectionWrapper.linkToDeath();
            }
        } catch (RemoteException e) {
            Log.d(TAG, "Error while setRemoteEmbeddedConnection " + e);
        }
    }

    private RemoteAccessibilityEmbeddedConnection getRemoteAccessibilityEmbeddedConnection() {
        return mConnectionWrapper;
    }

    void setScreenMatrix(Matrix m) {
        // If the screen matrix is identity or doesn't change, do nothing.
        if (m.isIdentity() || m.equals(mScreenMatrixForEmbeddedHierarchy)) {
            return;
        }

        try {
            final RemoteAccessibilityEmbeddedConnection wrapper =
                    getRemoteAccessibilityEmbeddedConnection();
            if (wrapper == null) {
                return;
            }
            m.getValues(mMatrixValues);
            wrapper.getConnection().setScreenMatrix(mMatrixValues);
            mScreenMatrixForEmbeddedHierarchy.set(m);
        } catch (RemoteException e) {
            Log.d(TAG, "Error while setScreenMatrix " + e);
        }
    }






}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy