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

Commit d40067dc authored by Robin Lee's avatar Robin Lee
Browse files

Stop contextual search showing in its own screenshots

Test: ContextualSearchManagerTest
Test: GtsInteractiveContextualSearchIntentTestCases
Bug: 390176823
Flag: android.app.contextualsearch.flags.contextual_search_window_layer
Change-Id: I1fc7c9ed8b742f3e55bf6cf929aa3de5debad80d
parent 81d5177c
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -27,7 +27,10 @@ flag {
    name: "contextual_search_window_layer"
    name: "contextual_search_window_layer"
    namespace: "sysui_integrations"
    namespace: "sysui_integrations"
    description: "Identify live contextual search UI to exclude from contextual search screenshot."
    description: "Identify live contextual search UI to exclude from contextual search screenshot."
    bug: "372510690"
    bug: "390176823"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
}


flag {
flag {
+14 −24
Original line number Original line Diff line number Diff line
@@ -27,10 +27,6 @@ import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;


import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
@@ -74,6 +70,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.Slog;
import android.view.IWindowManager;
import android.view.IWindowManager;
import android.window.ScreenCapture;
import android.window.ScreenCapture;
import android.window.ScreenCapture.ScreenshotHardwareBuffer;


import com.android.internal.R;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
@@ -333,10 +330,10 @@ public class ContextualSearchManagerService extends SystemService {
                isManagedProfileVisible = true;
                isManagedProfileVisible = true;
            }
            }
        }
        }
        final String csPackage = Objects.requireNonNull(launchIntent.getPackage());
        final int csUid = mPackageManager.getPackageUid(csPackage, /* flags */ 0L, userId);
        if (isAssistDataAllowed) {
        if (isAssistDataAllowed) {
            try {
            try {
                final String csPackage = Objects.requireNonNull(launchIntent.getPackage());
                final int csUid = mPackageManager.getPackageUid(csPackage, 0, 0);
                mAssistDataRequester.requestAssistData(
                mAssistDataRequester.requestAssistData(
                        activityTokens,
                        activityTokens,
                        /* fetchData */ true,
                        /* fetchData */ true,
@@ -350,17 +347,8 @@ public class ContextualSearchManagerService extends SystemService {
                Log.e(TAG, "Could not request assist data", e);
                Log.e(TAG, "Could not request assist data", e);
            }
            }
        }
        }
        final ScreenCapture.ScreenshotHardwareBuffer shb;
        final ScreenshotHardwareBuffer shb = mWmInternal.takeContextualSearchScreenshot(
        if (mWmInternal != null) {
                (Flags.contextualSearchWindowLayer() ? csUid : -1));
            shb = mWmInternal.takeAssistScreenshot(Set.of(
                    TYPE_STATUS_BAR,
                    TYPE_NAVIGATION_BAR,
                    TYPE_NAVIGATION_BAR_PANEL,
                    TYPE_POINTER));
        } else {
            if (DEBUG) Log.w(TAG, "Can't capture contextual screenshot: mWmInternal is null");
            shb = null;
        }
        final Bitmap bm = shb != null ? shb.asBitmap() : null;
        final Bitmap bm = shb != null ? shb.asBitmap() : null;
        // Now that everything is fetched, putting it in the launchIntent.
        // Now that everything is fetched, putting it in the launchIntent.
        if (bm != null) {
        if (bm != null) {
@@ -509,15 +497,17 @@ public class ContextualSearchManagerService extends SystemService {
                bundle.putParcelable(ContextualSearchManager.EXTRA_TOKEN, mToken);
                bundle.putParcelable(ContextualSearchManager.EXTRA_TOKEN, mToken);
                // We get take the screenshot with the system server's identity because the system
                // We get take the screenshot with the system server's identity because the system
                // server has READ_FRAME_BUFFER permission to get the screenshot.
                // server has READ_FRAME_BUFFER permission to get the screenshot.
                final int callingUid = Binder.getCallingUid();
                Binder.withCleanCallingIdentity(() -> {
                Binder.withCleanCallingIdentity(() -> {
                    if (mWmInternal != null) {
                    final ScreenshotHardwareBuffer shb =
                            mWmInternal.takeContextualSearchScreenshot(
                               (Flags.contextualSearchWindowLayer() ? callingUid : -1));
                    final Bitmap bm = shb != null ? shb.asBitmap() : null;
                    if (bm != null) {
                        bundle.putParcelable(ContextualSearchManager.EXTRA_SCREENSHOT,
                        bundle.putParcelable(ContextualSearchManager.EXTRA_SCREENSHOT,
                                mWmInternal.takeAssistScreenshot(Set.of(
                                bm.asShared());
                                        TYPE_STATUS_BAR,
                        bundle.putBoolean(ContextualSearchManager.EXTRA_FLAG_SECURE_FOUND,
                                        TYPE_NAVIGATION_BAR,
                                shb.containsSecureLayers());
                                        TYPE_NAVIGATION_BAR_PANEL,
                                        TYPE_POINTER))
                                .asBitmap().asShared());
                    }
                    }
                    try {
                    try {
                        callback.onResult(
                        callback.onResult(
+8 −9
Original line number Original line Diff line number Diff line
@@ -5255,7 +5255,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    /**
    /**
     * Creates a LayerCaptureArgs object to represent the entire DisplayContent
     * Creates a LayerCaptureArgs object to represent the entire DisplayContent
     */
     */
    LayerCaptureArgs getLayerCaptureArgs(Set<Integer> windowTypesToExclude) {
    LayerCaptureArgs getLayerCaptureArgs(@Nullable ToBooleanFunction<WindowState> predicate) {
        if (!mWmService.mPolicy.isScreenOn()) {
        if (!mWmService.mPolicy.isScreenOn()) {
            if (DEBUG_SCREENSHOT) {
            if (DEBUG_SCREENSHOT) {
                Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
                Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
@@ -5268,17 +5268,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        LayerCaptureArgs.Builder builder = new LayerCaptureArgs.Builder(getSurfaceControl())
        LayerCaptureArgs.Builder builder = new LayerCaptureArgs.Builder(getSurfaceControl())
                .setSourceCrop(mTmpRect);
                .setSourceCrop(mTmpRect);


        if (!windowTypesToExclude.isEmpty()) {
        if (predicate != null) {
            ArrayList<SurfaceControl> surfaceControls = new ArrayList<>();
            ArrayList<SurfaceControl> excludeLayers = new ArrayList<>();
            forAllWindows(
            forAllWindows(
                    window -> {
                    window -> {
                        if (windowTypesToExclude.contains(window.getWindowType())) {
                        if (!predicate.apply(window)) {
                            surfaceControls.add(window.mSurfaceControl);
                            excludeLayers.add(window.mSurfaceControl);
                        }
                        }
                    }, true
                    }, true);
            );
            if (!excludeLayers.isEmpty()) {
            if (!surfaceControls.isEmpty()) {
                builder.setExcludeLayers(excludeLayers.toArray(new SurfaceControl[0]));
                builder.setExcludeLayers(surfaceControls.toArray(new SurfaceControl[0]));
            }
            }
        }
        }
        return builder.build();
        return builder.build();
+11 −2
Original line number Original line Diff line number Diff line
@@ -1137,6 +1137,15 @@ public abstract class WindowManagerInternal {
     * Returns an instance of {@link ScreenshotHardwareBuffer} containing the current
     * Returns an instance of {@link ScreenshotHardwareBuffer} containing the current
     * screenshot.
     * screenshot.
     */
     */
    public abstract ScreenshotHardwareBuffer takeAssistScreenshot(
    public abstract ScreenshotHardwareBuffer takeAssistScreenshot();
            Set<Integer> windowTypesToExclude);

    /**
     * Returns an instance of {@link ScreenshotHardwareBuffer} containing the current
     * screenshot, excluding layers that are not appropriate to pass to contextual search
     * services - such as the cursor or any current contextual search window.
     *
     * @param uid the UID of the contextual search application. System alert windows belonging
     * to this UID will be excluded from the screenshot.
     */
    public abstract ScreenshotHardwareBuffer takeContextualSearchScreenshot(int uid);
}
}
+25 −6
Original line number Original line Diff line number Diff line
@@ -329,6 +329,7 @@ import android.window.WindowContainerToken;
import android.window.WindowContextInfo;
import android.window.WindowContextInfo;


import com.android.internal.R;
import com.android.internal.R;
import com.android.internal.util.ToBooleanFunction;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.internal.annotations.VisibleForTesting.Visibility;
@@ -4232,7 +4233,8 @@ public class WindowManagerService extends IWindowManager.Stub
    }
    }


    @Nullable
    @Nullable
    private ScreenshotHardwareBuffer takeAssistScreenshot(Set<Integer> windowTypesToExclude) {
    private ScreenshotHardwareBuffer takeAssistScreenshot(
            @Nullable ToBooleanFunction<WindowState> predicate) {
        if (!checkCallingPermission(READ_FRAME_BUFFER, "requestAssistScreenshot()")) {
        if (!checkCallingPermission(READ_FRAME_BUFFER, "requestAssistScreenshot()")) {
            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
        }
        }
@@ -4247,7 +4249,7 @@ public class WindowManagerService extends IWindowManager.Stub
                }
                }
                captureArgs = null;
                captureArgs = null;
            } else {
            } else {
                captureArgs = displayContent.getLayerCaptureArgs(windowTypesToExclude);
                captureArgs = displayContent.getLayerCaptureArgs(predicate);
            }
            }
        }
        }


@@ -4277,8 +4279,7 @@ public class WindowManagerService extends IWindowManager.Stub
     */
     */
    @Override
    @Override
    public boolean requestAssistScreenshot(final IAssistDataReceiver receiver) {
    public boolean requestAssistScreenshot(final IAssistDataReceiver receiver) {
        final ScreenshotHardwareBuffer shb =
        final ScreenshotHardwareBuffer shb = takeAssistScreenshot(/* predicate= */ null);
                takeAssistScreenshot(/* windowTypesToExclude= */ Set.of());
        final Bitmap bm = shb != null ? shb.asBitmap() : null;
        final Bitmap bm = shb != null ? shb.asBitmap() : null;
        FgThread.getHandler().post(() -> {
        FgThread.getHandler().post(() -> {
            try {
            try {
@@ -8935,9 +8936,27 @@ public class WindowManagerService extends IWindowManager.Stub
        }
        }


        @Override
        @Override
        public ScreenshotHardwareBuffer takeAssistScreenshot(Set<Integer> windowTypesToExclude) {
        public ScreenshotHardwareBuffer takeAssistScreenshot() {
            // WMS.takeAssistScreenshot takes care of the locking.
            // WMS.takeAssistScreenshot takes care of the locking.
            return WindowManagerService.this.takeAssistScreenshot(windowTypesToExclude);
            return WindowManagerService.this.takeAssistScreenshot(/* predicate */ null);
        }

        @Override
        public ScreenshotHardwareBuffer takeContextualSearchScreenshot(int uid) {
            // WMS.takeAssistScreenshot takes care of the locking.
            return WindowManagerService.this.takeAssistScreenshot(win -> {
                switch (win.getWindowType()) {
                    case LayoutParams.TYPE_STATUS_BAR:
                    case LayoutParams.TYPE_NAVIGATION_BAR:
                    case LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
                    case LayoutParams.TYPE_POINTER:
                        return false;
                    case LayoutParams.TYPE_APPLICATION_OVERLAY:
                        return uid != win.getOwningUid();
                    default:
                        return true;
                }
            });
        }
        }
    }
    }


Loading