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

Commit 19eb5895 authored by Peter Visontay's avatar Peter Visontay
Browse files

Log an App Op when an accessibility action is performed.

Bug: 63907873
Test: manually tested that the app op is being logged for TalkBack and a 3rd party accessibility service. Ran UIAutomator-based tests to check that they work as expected.
Change-Id: I1a40d4ead52ba2258cc7ddc8be594a13895d8340
parent 5c9d8019
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -260,8 +260,10 @@ public class AppOpsManager {
    public static final int OP_REQUEST_DELETE_PACKAGES = 72;
    /** @hide Bind an accessibility service. */
    public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73;
    /** @hide Interact with the system UI via an Accessibility Service */
    public static final int OP_PERFORM_ACCESSIBILITY_ACTION = 74;
    /** @hide */
    public static final int _NUM_OP = 74;
    public static final int _NUM_OP = 75;

    /** Access to coarse location information. */
    public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -506,6 +508,7 @@ public class AppOpsManager {
            OP_CHANGE_WIFI_STATE,
            OP_REQUEST_DELETE_PACKAGES,
            OP_BIND_ACCESSIBILITY_SERVICE,
            OP_PERFORM_ACCESSIBILITY_ACTION,
    };

    /**
@@ -587,6 +590,7 @@ public class AppOpsManager {
            null, // OP_CHANGE_WIFI_STATE
            null, // OP_REQUEST_DELETE_PACKAGES
            null, // OP_BIND_ACCESSIBILITY_SERVICE
            null, // OP_PERFORM_ACCESSIBILITY_ACTION
    };

    /**
@@ -668,6 +672,7 @@ public class AppOpsManager {
            "CHANGE_WIFI_STATE",
            "REQUEST_DELETE_PACKAGES",
            "BIND_ACCESSIBILITY_SERVICE",
            "OP_PERFORM_ACCESSIBILITY_ACTION",
    };

    /**
@@ -749,6 +754,7 @@ public class AppOpsManager {
            Manifest.permission.CHANGE_WIFI_STATE,
            Manifest.permission.REQUEST_DELETE_PACKAGES,
            Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
            null, // no permission for OP_PERFORM_ACCESSIBILITY_ACTION
    };

    /**
@@ -831,6 +837,7 @@ public class AppOpsManager {
            null, // OP_CHANGE_WIFI_STATE
            null, // REQUEST_DELETE_PACKAGES
            null, // OP_BIND_ACCESSIBILITY_SERVICE
            null, // OP_PERFORM_ACCESSIBILITY_ACTION
    };

    /**
@@ -912,6 +919,7 @@ public class AppOpsManager {
            false, // OP_CHANGE_WIFI_STATE
            false, // OP_REQUEST_DELETE_PACKAGES
            false, // OP_BIND_ACCESSIBILITY_SERVICE
            false, // OP_PERFORM_ACCESSIBILITY_ACTION
    };

    /**
@@ -992,6 +1000,7 @@ public class AppOpsManager {
            AppOpsManager.MODE_ALLOWED,  // OP_CHANGE_WIFI_STATE
            AppOpsManager.MODE_ALLOWED,  // REQUEST_DELETE_PACKAGES
            AppOpsManager.MODE_ALLOWED,  // OP_BIND_ACCESSIBILITY_SERVICE
            AppOpsManager.MODE_ALLOWED,  // OP_PERFORM_ACCESSIBILITY_ACTION
    };

    /**
@@ -1076,6 +1085,7 @@ public class AppOpsManager {
            false, // OP_CHANGE_WIFI_STATE
            false, // OP_REQUEST_DELETE_PACKAGES
            false, // OP_BIND_ACCESSIBILITY_SERVICE
            false, // OP_PERFORM_ACCESSIBILITY_ACTION
    };

    /**
+24 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.accessibilityservice.IAccessibilityServiceClient;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -39,7 +40,9 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
import android.util.SparseArray;
import android.view.KeyEvent;
@@ -93,6 +96,7 @@ abstract class AccessibilityClientConnection extends IAccessibilityServiceConnec
    protected final Object mLock;

    protected final SecurityPolicy mSecurityPolicy;
    private final AppOpsManager mAppOpsManager;

    // The service that's bound to this instance. Whenever this value is non-null, this
    // object is registered as a death recipient
@@ -250,6 +254,7 @@ abstract class AccessibilityClientConnection extends IAccessibilityServiceConnec
        mAccessibilityServiceInfo = accessibilityServiceInfo;
        mLock = lock;
        mSecurityPolicy = securityPolicy;
        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        mGlobalActionPerformer = globalActionPerfomer;
        mSystemSupport = systemSupport;
        mInvocationHandler = new InvocationHandler(mainHandler.getLooper());
@@ -706,6 +711,16 @@ abstract class AccessibilityClientConnection extends IAccessibilityServiceConnec
            long accessibilityNodeId, int action, Bundle arguments, int interactionId,
            IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
            throws RemoteException {

        // Skip this if the caller is the Accessibility InteractionBridge.
        if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) {
            if (mAppOpsManager.noteOp(AppOpsManager.OP_PERFORM_ACCESSIBILITY_ACTION,
                    Binder.getCallingUid(), mComponentName.getPackageName())
                    != AppOpsManager.MODE_ALLOWED) {
                return false;
            }
        }

        final int resolvedWindowId;
        IAccessibilityInteractionConnection connection = null;
        synchronized (mLock) {
@@ -725,6 +740,15 @@ abstract class AccessibilityClientConnection extends IAccessibilityServiceConnec

    @Override
    public boolean performGlobalAction(int action) {
        // Skip this if the caller is the Accessibility InteractionBridge.
        if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) {
            if (mAppOpsManager.noteOp(AppOpsManager.OP_PERFORM_ACCESSIBILITY_ACTION,
                    Binder.getCallingUid(), mComponentName.getPackageName())
                    != AppOpsManager.MODE_ALLOWED) {
                return false;
            }
        }

        synchronized (mLock) {
            if (!isCalledForCurrentUserLocked()) {
                return false;