diff options
| author | 2025-01-31 07:25:29 -0800 | |
|---|---|---|
| committer | 2025-01-31 07:25:29 -0800 | |
| commit | daee64130935cd630ed3f60a02580f16bf0853cd (patch) | |
| tree | 80b3029bd14e7a054059d9bf19dc4e039ec93f6f | |
| parent | 74cfeceb8f3ed345c683351fa80c7f1620de09e9 (diff) | |
| parent | d40067dc50e6ae6f0bbfc0ee307f9c506284a40e (diff) | |
Merge "Stop contextual search showing in its own screenshots" into main
6 files changed, 64 insertions, 45 deletions
diff --git a/core/java/android/app/contextualsearch/flags.aconfig b/core/java/android/app/contextualsearch/flags.aconfig index c19921dcdc61..d81ec1e8b883 100644 --- a/core/java/android/app/contextualsearch/flags.aconfig +++ b/core/java/android/app/contextualsearch/flags.aconfig @@ -27,7 +27,10 @@ flag { name: "contextual_search_window_layer" namespace: "sysui_integrations" description: "Identify live contextual search UI to exclude from contextual search screenshot." - bug: "372510690" + bug: "390176823" + metadata { + purpose: PURPOSE_BUGFIX + } } flag { @@ -35,4 +38,4 @@ flag { namespace: "sysui_integrations" description: "Add audio playing status to the contextual search invocation intent." bug: "372935419" -}
\ No newline at end of file +} diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java index df47c98d6433..89c9d690a82c 100644 --- a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java +++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java @@ -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_UNAWARE; 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_STRUCTURE; @@ -74,6 +70,7 @@ import android.util.Log; import android.util.Slog; import android.view.IWindowManager; import android.window.ScreenCapture; +import android.window.ScreenCapture.ScreenshotHardwareBuffer; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; @@ -333,10 +330,10 @@ public class ContextualSearchManagerService extends SystemService { isManagedProfileVisible = true; } } + final String csPackage = Objects.requireNonNull(launchIntent.getPackage()); + final int csUid = mPackageManager.getPackageUid(csPackage, /* flags */ 0L, userId); if (isAssistDataAllowed) { try { - final String csPackage = Objects.requireNonNull(launchIntent.getPackage()); - final int csUid = mPackageManager.getPackageUid(csPackage, 0, 0); mAssistDataRequester.requestAssistData( activityTokens, /* fetchData */ true, @@ -350,17 +347,8 @@ public class ContextualSearchManagerService extends SystemService { Log.e(TAG, "Could not request assist data", e); } } - final ScreenCapture.ScreenshotHardwareBuffer shb; - if (mWmInternal != null) { - 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 ScreenshotHardwareBuffer shb = mWmInternal.takeContextualSearchScreenshot( + (Flags.contextualSearchWindowLayer() ? csUid : -1)); final Bitmap bm = shb != null ? shb.asBitmap() : null; // Now that everything is fetched, putting it in the launchIntent. if (bm != null) { @@ -509,15 +497,17 @@ public class ContextualSearchManagerService extends SystemService { bundle.putParcelable(ContextualSearchManager.EXTRA_TOKEN, mToken); // We get take the screenshot with the system server's identity because the system // server has READ_FRAME_BUFFER permission to get the screenshot. + final int callingUid = Binder.getCallingUid(); 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, - mWmInternal.takeAssistScreenshot(Set.of( - TYPE_STATUS_BAR, - TYPE_NAVIGATION_BAR, - TYPE_NAVIGATION_BAR_PANEL, - TYPE_POINTER)) - .asBitmap().asShared()); + bm.asShared()); + bundle.putBoolean(ContextualSearchManager.EXTRA_FLAG_SECURE_FOUND, + shb.containsSecureLayers()); } try { callback.onResult( diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index a0d2d260b39e..ecf2787a2080 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5165,7 +5165,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp /** * 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 (DEBUG_SCREENSHOT) { Slog.i(TAG_WM, "Attempted to take screenshot while display was off."); @@ -5178,17 +5178,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp LayerCaptureArgs.Builder builder = new LayerCaptureArgs.Builder(getSurfaceControl()) .setSourceCrop(mTmpRect); - if (!windowTypesToExclude.isEmpty()) { - ArrayList<SurfaceControl> surfaceControls = new ArrayList<>(); + if (predicate != null) { + ArrayList<SurfaceControl> excludeLayers = new ArrayList<>(); forAllWindows( window -> { - if (windowTypesToExclude.contains(window.getWindowType())) { - surfaceControls.add(window.mSurfaceControl); + if (!predicate.apply(window)) { + excludeLayers.add(window.mSurfaceControl); } - }, true - ); - if (!surfaceControls.isEmpty()) { - builder.setExcludeLayers(surfaceControls.toArray(new SurfaceControl[0])); + }, true); + if (!excludeLayers.isEmpty()) { + builder.setExcludeLayers(excludeLayers.toArray(new SurfaceControl[0])); } } return builder.build(); diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index c77b1d9a7bcf..6e224f07fcdc 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -1137,6 +1137,15 @@ public abstract class WindowManagerInternal { * Returns an instance of {@link ScreenshotHardwareBuffer} containing the current * screenshot. */ - public abstract ScreenshotHardwareBuffer takeAssistScreenshot( - Set<Integer> windowTypesToExclude); + public abstract ScreenshotHardwareBuffer takeAssistScreenshot(); + + /** + * 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); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 3a1d652f82d4..7f1924005b2f 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -325,6 +325,7 @@ import android.window.WindowContainerToken; import android.window.WindowContextInfo; import com.android.internal.R; +import com.android.internal.util.ToBooleanFunction; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; @@ -4159,7 +4160,8 @@ public class WindowManagerService extends IWindowManager.Stub } @Nullable - private ScreenshotHardwareBuffer takeAssistScreenshot(Set<Integer> windowTypesToExclude) { + private ScreenshotHardwareBuffer takeAssistScreenshot( + @Nullable ToBooleanFunction<WindowState> predicate) { if (!checkCallingPermission(READ_FRAME_BUFFER, "requestAssistScreenshot()")) { throw new SecurityException("Requires READ_FRAME_BUFFER permission"); } @@ -4174,7 +4176,7 @@ public class WindowManagerService extends IWindowManager.Stub } captureArgs = null; } else { - captureArgs = displayContent.getLayerCaptureArgs(windowTypesToExclude); + captureArgs = displayContent.getLayerCaptureArgs(predicate); } } @@ -4204,8 +4206,7 @@ public class WindowManagerService extends IWindowManager.Stub */ @Override public boolean requestAssistScreenshot(final IAssistDataReceiver receiver) { - final ScreenshotHardwareBuffer shb = - takeAssistScreenshot(/* windowTypesToExclude= */ Set.of()); + final ScreenshotHardwareBuffer shb = takeAssistScreenshot(/* predicate= */ null); final Bitmap bm = shb != null ? shb.asBitmap() : null; FgThread.getHandler().post(() -> { try { @@ -8618,9 +8619,27 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public ScreenshotHardwareBuffer takeAssistScreenshot(Set<Integer> windowTypesToExclude) { + public ScreenshotHardwareBuffer takeAssistScreenshot() { // 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; + } + }); } } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 7e7a53148603..cd1c48554be9 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -2747,8 +2747,7 @@ public class VoiceInteractionManagerService extends SystemService { isManagedProfileVisible = true; } } - final ScreenCapture.ScreenshotHardwareBuffer shb = - mWmInternal.takeAssistScreenshot(/* windowTypesToExclude= */ Set.of()); + final ScreenCapture.ScreenshotHardwareBuffer shb = mWmInternal.takeAssistScreenshot(); final Bitmap bm = shb != null ? shb.asBitmap() : null; // Now that everything is fetched, putting it in the launchIntent. if (bm != null) { |