Loading core/java/android/app/contextualsearch/ContextualSearchManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -261,7 +261,8 @@ public final class ContextualSearchManager { * <li>Resolves the activity using the package name and intent filter. The package name * is fetched from the config specified in ContextualSearchManagerService. * The activity must have ACTION_LAUNCH_CONTEXTUAL_SEARCH specified in its manifest. * <li>Puts the required extras in the launch intent. * <li>Puts the required extras in the launch intent, which may include a * {@link android.media.projection.MediaProjection} session. * <li>Launches the activity. * </ul> * </p> Loading core/java/android/app/contextualsearch/flags.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,16 @@ flag { } } flag { name: "contextual_search_media_projection" namespace: "sysui_integrations" description: "Attach MediaProjection session to contextual search invocation intent." bug: "395054309" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "include_audio_playing_status" namespace: "sysui_integrations" Loading services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java +36 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; import android.graphics.Bitmap; import android.media.AudioManager; import android.media.projection.IMediaProjection; import android.media.projection.IMediaProjectionManager; import android.media.projection.MediaProjectionManager; import android.os.Binder; import android.os.Bundle; import android.os.Handler; Loading @@ -70,6 +73,7 @@ import android.os.UserManager; import android.provider.Settings; import android.util.Log; import android.util.Slog; import android.view.Display; import android.view.IWindowManager; import android.window.ScreenCapture.ScreenshotHardwareBuffer; Loading Loading @@ -380,6 +384,13 @@ public class ContextualSearchManagerService extends SystemService { launchIntent.putExtra(ContextualSearchManager.EXTRA_SCREENSHOT, bm.asShared()); } } IMediaProjection mediaProjection = getMediaProjection(csUid, csPackage); if (mediaProjection != null) { launchIntent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, mediaProjection.asBinder()); } launchIntent.putExtra(ContextualSearchManager.EXTRA_IS_MANAGED_PROFILE_VISIBLE, isManagedProfileVisible); // Only put the list of visible package names if assist data is allowed Loading @@ -390,6 +401,23 @@ public class ContextualSearchManagerService extends SystemService { return launchIntent; } private IMediaProjection getMediaProjection(int uid, String packageName) { if (Flags.contextualSearchMediaProjection()) { return Binder.withCleanCallingIdentity(() -> { IBinder binder = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); IMediaProjectionManager mediaProjectionManager = IMediaProjectionManager.Stub.asInterface(binder); IMediaProjection mediaProjection = mediaProjectionManager.createProjection(uid, packageName, MediaProjectionManager.TYPE_SCREEN_CAPTURE, false, Display.DEFAULT_DISPLAY); return mediaProjection; }); } else { return null; } } @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS) private int invokeContextualSearchIntent(Intent launchIntent, final int userId) { // Contextual search starts with a frozen screen - so we launch without Loading Loading @@ -549,9 +577,12 @@ public class ContextualSearchManagerService extends SystemService { issueToken(); Bundle bundle = new Bundle(); 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(); IMediaProjection mediaProjection = getMediaProjection(callingUid, getContextualSearchPackageName()); Binder.withCleanCallingIdentity(() -> { final ScreenshotHardwareBuffer shb = mWmInternal.takeContextualSearchScreenshot( Loading @@ -563,6 +594,11 @@ public class ContextualSearchManagerService extends SystemService { bundle.putBoolean(ContextualSearchManager.EXTRA_FLAG_SECURE_FOUND, shb.containsSecureLayers()); } if (mediaProjection != null) { bundle.putBinder(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, mediaProjection.asBinder()); } try { callback.onResult( new ContextualSearchState(null, null, bundle)); Loading services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -776,7 +776,7 @@ public final class MediaProjectionManagerService extends SystemService int type, boolean isPermanentGrant, int displayId) { if (mContext.checkCallingPermission(MANAGE_MEDIA_PROJECTION) if (mContext.checkCallingOrSelfPermission(MANAGE_MEDIA_PROJECTION) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to grant " + "projection permission"); Loading Loading
core/java/android/app/contextualsearch/ContextualSearchManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -261,7 +261,8 @@ public final class ContextualSearchManager { * <li>Resolves the activity using the package name and intent filter. The package name * is fetched from the config specified in ContextualSearchManagerService. * The activity must have ACTION_LAUNCH_CONTEXTUAL_SEARCH specified in its manifest. * <li>Puts the required extras in the launch intent. * <li>Puts the required extras in the launch intent, which may include a * {@link android.media.projection.MediaProjection} session. * <li>Launches the activity. * </ul> * </p> Loading
core/java/android/app/contextualsearch/flags.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,16 @@ flag { } } flag { name: "contextual_search_media_projection" namespace: "sysui_integrations" description: "Attach MediaProjection session to contextual search invocation intent." bug: "395054309" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "include_audio_playing_status" namespace: "sysui_integrations" Loading
services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java +36 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; import android.graphics.Bitmap; import android.media.AudioManager; import android.media.projection.IMediaProjection; import android.media.projection.IMediaProjectionManager; import android.media.projection.MediaProjectionManager; import android.os.Binder; import android.os.Bundle; import android.os.Handler; Loading @@ -70,6 +73,7 @@ import android.os.UserManager; import android.provider.Settings; import android.util.Log; import android.util.Slog; import android.view.Display; import android.view.IWindowManager; import android.window.ScreenCapture.ScreenshotHardwareBuffer; Loading Loading @@ -380,6 +384,13 @@ public class ContextualSearchManagerService extends SystemService { launchIntent.putExtra(ContextualSearchManager.EXTRA_SCREENSHOT, bm.asShared()); } } IMediaProjection mediaProjection = getMediaProjection(csUid, csPackage); if (mediaProjection != null) { launchIntent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, mediaProjection.asBinder()); } launchIntent.putExtra(ContextualSearchManager.EXTRA_IS_MANAGED_PROFILE_VISIBLE, isManagedProfileVisible); // Only put the list of visible package names if assist data is allowed Loading @@ -390,6 +401,23 @@ public class ContextualSearchManagerService extends SystemService { return launchIntent; } private IMediaProjection getMediaProjection(int uid, String packageName) { if (Flags.contextualSearchMediaProjection()) { return Binder.withCleanCallingIdentity(() -> { IBinder binder = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); IMediaProjectionManager mediaProjectionManager = IMediaProjectionManager.Stub.asInterface(binder); IMediaProjection mediaProjection = mediaProjectionManager.createProjection(uid, packageName, MediaProjectionManager.TYPE_SCREEN_CAPTURE, false, Display.DEFAULT_DISPLAY); return mediaProjection; }); } else { return null; } } @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS) private int invokeContextualSearchIntent(Intent launchIntent, final int userId) { // Contextual search starts with a frozen screen - so we launch without Loading Loading @@ -549,9 +577,12 @@ public class ContextualSearchManagerService extends SystemService { issueToken(); Bundle bundle = new Bundle(); 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(); IMediaProjection mediaProjection = getMediaProjection(callingUid, getContextualSearchPackageName()); Binder.withCleanCallingIdentity(() -> { final ScreenshotHardwareBuffer shb = mWmInternal.takeContextualSearchScreenshot( Loading @@ -563,6 +594,11 @@ public class ContextualSearchManagerService extends SystemService { bundle.putBoolean(ContextualSearchManager.EXTRA_FLAG_SECURE_FOUND, shb.containsSecureLayers()); } if (mediaProjection != null) { bundle.putBinder(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, mediaProjection.asBinder()); } try { callback.onResult( new ContextualSearchState(null, null, bundle)); Loading
services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -776,7 +776,7 @@ public final class MediaProjectionManagerService extends SystemService int type, boolean isPermanentGrant, int displayId) { if (mContext.checkCallingPermission(MANAGE_MEDIA_PROJECTION) if (mContext.checkCallingOrSelfPermission(MANAGE_MEDIA_PROJECTION) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to grant " + "projection permission"); Loading