From 50b8dad1e206a8f7050831b5cb988e8be6f65425 Mon Sep 17 00:00:00 2001 From: dakinola Date: Wed, 8 Mar 2023 17:52:13 +0000 Subject: [PATCH] MediaProjection: stop media projection activity result from being stored after being sent Ensure that activity results force sent for media projection are only scheduled to be sent once, and not stored to be re-sent on when resuming. Also update the documentation for MediaProjection#createVirtualDisplay to properly document a previously known outcome of a SecurityException being thrown. Bug: 271577674 Fix: 271577674 Test: atest WmTests:ActivityRecordTests Change-Id: Ie43290a1ddbd9dedfe9217d7c19c1d5b890d4331 --- .../android/media/projection/MediaProjection.java | 4 ++++ .../projection/MediaProjectionManagerService.java | 2 +- .../java/com/android/server/wm/ActivityRecord.java | 11 ++++++++--- .../com/android/server/wm/ActivityRecordTests.java | 2 ++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java index 9d0662bfb52f7..6ed8f090608e8 100644 --- a/media/java/android/media/projection/MediaProjection.java +++ b/media/java/android/media/projection/MediaProjection.java @@ -180,6 +180,10 @@ public final class MediaProjection { * is registered. If the target SDK is less than * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U}, no * exception is thrown. + * @throws SecurityException If attempting to create a new virtual display associated with this + * MediaProjection instance after it has been stopped by invoking + * {@link #stop()}. + * * @see VirtualDisplay * @see VirtualDisplay.Callback */ diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java index 48326188e215b..b75b7d4daacde 100644 --- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java @@ -67,7 +67,7 @@ import java.util.Map; * The {@link MediaProjectionManagerService} manages the creation and lifetime of MediaProjections, * as well as the capabilities they grant. Any service using MediaProjection tokens as permission * grants must validate the token before use by calling {@link - * IMediaProjectionService#isCurrentProjection}. + * IMediaProjectionManager#isCurrentProjection}. */ public final class MediaProjectionManagerService extends SystemService implements Watchdog.Monitor { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index d249f8c3ab403..1e22178a11bcf 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -465,7 +465,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final int launchedFromPid; // always the pid who started the activity. final int launchedFromUid; // always the uid who started the activity. final String launchedFromPackage; // always the package who started the activity. - final @Nullable String launchedFromFeatureId; // always the feature in launchedFromPackage + @Nullable + final String launchedFromFeatureId; // always the feature in launchedFromPackage private final int mLaunchSourceType; // original launch source type final Intent intent; // the original intent that generated us final String shortComponentName; // the short component name of the intent @@ -731,7 +732,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** * Solely for reporting to ActivityMetricsLogger. Just tracks whether, the last time this - * Actiivty was part of a syncset, all windows were ready by the time the sync was ready (vs. + * Activity was part of a syncset, all windows were ready by the time the sync was ready (vs. * only the top-occluding ones). The assumption here is if some were not ready, they were * covered with starting-window/splash-screen. */ @@ -4769,6 +4770,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } catch (RemoteException e) { Slog.w(TAG, "Exception thrown sending result to " + this, e); } + // We return here to ensure that result for media projection setup is not stored as a + // pending result after being scheduled. This is to prevent this stored result being + // sent again when the destination component is resumed. + return; } addResultLocked(null /* from */, resultWho, requestCode, resultCode, data); @@ -4776,7 +4781,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** * Provides a lifecycle item for the current stat. Only to be used when force sending an - * activity result (as part of MeidaProjection setup). Does not support the following states: + * activity result (as part of MediaProjection setup). Does not support the following states: * {@link State#INITIALIZING}, {@link State#RESTARTING_PROCESS}, * {@link State#FINISHING}, {@link State#DESTROYING}, {@link State#DESTROYED}. It does not make * sense to force send a result to an activity in these states. Does not support diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 6147633f624a7..1a635a9e589f0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1205,6 +1205,8 @@ public class ActivityRecordTests extends WindowTestsBase { any(ClientTransaction.class)); } catch (RemoteException ignored) { } + + assertNull(targetActivity.results); } @Test