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

Commit 366b633f authored by Daniel Norman's avatar Daniel Norman Committed by Android (Google) Code Review
Browse files

Merge "Stop blocking preinstalled a11y tools from taking FLAG_SECURE screenshots." into main

parents d9449dc3 22b4f81b
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.view.accessibility.AccessibilityNodeProvider;
import android.view.accessibility.AccessibilityRequestPreparer;
import android.view.accessibility.Flags;
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
import android.view.accessibility.IWindowSurfaceInfoCallback;
import android.window.ScreenCapture;

import com.android.internal.R;
@@ -631,6 +632,25 @@ public final class AccessibilityInteractionController {
        }
    }

    /**
     * Provide info for taking a screenshot of this app window.
     */
    public void getWindowSurfaceInfoClientThread(IWindowSurfaceInfoCallback callback) {
        Message message = PooledLambda.obtainMessage(
                AccessibilityInteractionController::getWindowSurfaceInfoUiThread,
                this, callback);
        mHandler.sendMessage(message);
    }

    private void getWindowSurfaceInfoUiThread(IWindowSurfaceInfoCallback callback) {
        try {
            callback.provideWindowSurfaceInfo(mViewRootImpl.getWindowFlags(), Process.myUid(),
                    mViewRootImpl.getSurfaceControl());
        } catch (RemoteException re) {
            // ignore - the other side will time out
        }
    }

    public void findFocusClientThread(long accessibilityNodeId, int focusType,
            Region interactiveRegion, int interactionId,
            IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
+10 −0
Original line number Diff line number Diff line
@@ -254,6 +254,7 @@ import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityEmbeddedConnection;
import android.view.accessibility.IAccessibilityInteractionConnection;
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
import android.view.accessibility.IWindowSurfaceInfoCallback;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.autofill.AutofillManager;
@@ -12285,6 +12286,15 @@ public final class ViewRootImpl implements ViewParent,
            }
        }
        @Override
        public void getWindowSurfaceInfo(IWindowSurfaceInfoCallback callback) {
            ViewRootImpl viewRootImpl = mViewRootImpl.get();
            if (viewRootImpl != null && viewRootImpl.mView != null) {
                viewRootImpl.getAccessibilityInteractionController()
                        .getWindowSurfaceInfoClientThread(callback);
            }
        }
        public void attachAccessibilityOverlayToWindow(
                SurfaceControl sc,
                int interactionId,
+3 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.view.MagnificationSpec;
import android.view.SurfaceControl;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
import android.view.accessibility.IWindowSurfaceInfoCallback;
import android.window.ScreenCapture;

/**
@@ -67,5 +68,7 @@ oneway interface IAccessibilityInteractionConnection {
        in ScreenCapture.ScreenCaptureListener listener,
        IAccessibilityInteractionConnectionCallback callback);

    void getWindowSurfaceInfo(IWindowSurfaceInfoCallback callback);

    void attachAccessibilityOverlayToWindow(in SurfaceControl sc, int interactionId, in IAccessibilityInteractionConnectionCallback callback);
}
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.accessibility;

import android.view.SurfaceControl;

/**
 * Callback for an app to provide AbstractAccessibilityServiceConnection with window and surface
 * information necessary for system_server to take a screenshot of the app window.
 * @hide
 */
oneway interface IWindowSurfaceInfoCallback {

    /**
     * Provide info from ViewRootImpl for taking a screenshot of this app window.
     *
     * @param windowFlags the window flags of ViewRootImpl
     * @param processUid the process (kernel) uid, NOT the user ID, required for
                         SurfaceFlinger screenshots
     * @param surfaceControl the surface of ViewRootImpl
     */
    @RequiresNoPermission
    void provideWindowSurfaceInfo(int windowFlags, int processUid,
            in SurfaceControl surfaceControl);
}
+17 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.app.Instrumentation;
import android.app.Service;
import android.app.UiAutomation;
import android.graphics.Rect;
import android.os.Process;
import android.os.SystemClock;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityEvent;
@@ -32,6 +33,7 @@ import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityTestActivity;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IWindowSurfaceInfoCallback;

import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -47,6 +49,7 @@ import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;

import java.util.List;
import java.util.concurrent.TimeoutException;
@@ -136,6 +139,20 @@ public class AccessibilityInteractionControllerTest {
        }
    }

    @Test
    public void getWindowSurfaceInfo_shouldCallCallbackWithWindowSurfaceDataFromVri()
            throws Exception {
        final ViewRootImpl vri = mButton.getRootView().getViewRootImpl();
        IWindowSurfaceInfoCallback callback = Mockito.mock(IWindowSurfaceInfoCallback.class);

        sInstrumentation.runOnMainSync(() ->
                mAccessibilityInteractionController.getWindowSurfaceInfoClientThread(callback));
        sInstrumentation.waitForIdleSync();

        Mockito.verify(callback).provideWindowSurfaceInfo(
                vri.getWindowFlags(), Process.myUid(), vri.getSurfaceControl());
    }

    private void launchActivity() {
        final Object waitObject = new Object();
        final int[] location = new int[2];
Loading