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

Commit cd156e46 authored by Marvin Ramin's avatar Marvin Ramin
Browse files

Add MediaProjection session to ContextualSearch Intent

When launching the ContextualSearch target, the Intent also contains a
valid MediaProjection token. This can be used to call
MediaProjectionManager#getProjection.

Bug: 395054309
Flag: android.app.contextualsearch.flags.contextual_search_media_projection
Test: atest ContextualSearchManagerTest
Change-Id: I2fb296de1cd5ac734798e04abb9c8c24b39a6e0b
parent bdd9d83c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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>
+10 −0
Original line number Diff line number Diff line
@@ -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"
+36 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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
@@ -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
@@ -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(
@@ -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));
+1 −1
Original line number Diff line number Diff line
@@ -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");