summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java6
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionStopController.java25
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionStopControllerTest.java57
3 files changed, 74 insertions, 14 deletions
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 c460465bfb11..fce008c23350 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -175,7 +175,7 @@ public final class MediaProjectionManagerService extends SystemService
private void maybeStopMediaProjection(int reason) {
synchronized (mLock) {
- if (!mMediaProjectionStopController.isExemptFromStopping(mProjectionGrant)) {
+ if (!mMediaProjectionStopController.isExemptFromStopping(mProjectionGrant, reason)) {
Slog.d(TAG, "Content Recording: Stopping MediaProjection due to "
+ MediaProjectionStopController.stopReasonToString(reason));
mProjectionGrant.stop();
@@ -1272,6 +1272,10 @@ public final class MediaProjectionManagerService extends SystemService
return mDisplayId;
}
+ long getCreateTimeMillis() {
+ return mCreateTimeMs;
+ }
+
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
@Override
public boolean isValid() {
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionStopController.java b/services/core/java/com/android/server/media/projection/MediaProjectionStopController.java
index f5b26c41015e..c018e6bc1dc7 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionStopController.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionStopController.java
@@ -27,6 +27,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
+import android.os.SystemClock;
import android.provider.Settings;
import android.telecom.TelecomManager;
import android.telephony.TelephonyCallback;
@@ -46,6 +47,8 @@ public class MediaProjectionStopController {
private static final String TAG = "MediaProjectionStopController";
@VisibleForTesting
+ static final int STOP_REASON_UNKNOWN = 0;
+ @VisibleForTesting
static final int STOP_REASON_KEYGUARD = 1;
@VisibleForTesting
static final int STOP_REASON_CALL_END = 2;
@@ -61,6 +64,7 @@ public class MediaProjectionStopController {
private final ContentResolver mContentResolver;
private boolean mIsInCall;
+ private long mLastCallStartTimeMillis;
public MediaProjectionStopController(Context context, Consumer<Integer> stopReasonConsumer) {
mStopReasonConsumer = stopReasonConsumer;
@@ -95,8 +99,8 @@ public class MediaProjectionStopController {
* Checks whether the given projection grant is exempt from stopping restrictions.
*/
public boolean isExemptFromStopping(
- MediaProjectionManagerService.MediaProjection projectionGrant) {
- return isExempt(projectionGrant, false);
+ MediaProjectionManagerService.MediaProjection projectionGrant, int stopReason) {
+ return isExempt(projectionGrant, stopReason, false);
}
/**
@@ -110,7 +114,8 @@ public class MediaProjectionStopController {
* MediaProjection session
*/
private boolean isExempt(
- MediaProjectionManagerService.MediaProjection projectionGrant, boolean forStart) {
+ MediaProjectionManagerService.MediaProjection projectionGrant, int stopReason,
+ boolean forStart) {
if (projectionGrant == null || projectionGrant.packageName == null) {
return true;
}
@@ -151,6 +156,14 @@ public class MediaProjectionStopController {
return true;
}
+ if (stopReason == STOP_REASON_CALL_END
+ && projectionGrant.getCreateTimeMillis() < mLastCallStartTimeMillis) {
+ Slog.v(TAG,
+ "Continuing MediaProjection as (phone) call started after MediaProjection was"
+ + " created.");
+ return true;
+ }
+
return false;
}
@@ -167,7 +180,7 @@ public class MediaProjectionStopController {
return false;
}
- if (isExempt(projectionGrant, true)) {
+ if (isExempt(projectionGrant, STOP_REASON_UNKNOWN, true)) {
return false;
}
return true;
@@ -188,9 +201,13 @@ public class MediaProjectionStopController {
return;
}
boolean isInCall = mTelecomManager.isInCall();
+ if (isInCall) {
+ mLastCallStartTimeMillis = SystemClock.uptimeMillis();
+ }
if (isInCall == mIsInCall) {
return;
}
+
if (mIsInCall && !isInCall) {
mStopReasonConsumer.accept(STOP_REASON_CALL_END);
}
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionStopControllerTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionStopControllerTest.java
index 89d2d2847007..affcfc14034e 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionStopControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionStopControllerTest.java
@@ -194,12 +194,14 @@ public class MediaProjectionStopControllerTest {
@Test
public void testExemptFromStoppingNullProjection() throws Exception {
- assertThat(mStopController.isExemptFromStopping(null)).isTrue();
+ assertThat(mStopController.isExemptFromStopping(null,
+ MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue();
}
@Test
public void testExemptFromStoppingInvalidProjection() throws Exception {
- assertThat(mStopController.isExemptFromStopping(createMediaProjection(null))).isTrue();
+ assertThat(mStopController.isExemptFromStopping(createMediaProjection(null),
+ MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue();
}
@Test
@@ -213,7 +215,8 @@ public class MediaProjectionStopControllerTest {
Settings.Global.putInt(mContext.getContentResolver(),
DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, 1);
- assertThat(mStopController.isExemptFromStopping(mediaProjection)).isTrue();
+ assertThat(mStopController.isExemptFromStopping(mediaProjection,
+ MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue();
} finally {
Settings.Global.putInt(mContext.getContentResolver(),
DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, value);
@@ -230,7 +233,8 @@ public class MediaProjectionStopControllerTest {
eq(mediaProjection.uid), eq(mediaProjection.packageName),
nullable(String.class),
nullable(String.class));
- assertThat(mStopController.isExemptFromStopping(mediaProjection)).isTrue();
+ assertThat(mStopController.isExemptFromStopping(mediaProjection,
+ MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue();
}
@Test
@@ -244,7 +248,8 @@ public class MediaProjectionStopControllerTest {
doReturn(PackageManager.PERMISSION_DENIED).when(
mPackageManager).checkPermission(
RECORD_SENSITIVE_CONTENT, mediaProjection.packageName);
- assertThat(mStopController.isExemptFromStopping(mediaProjection)).isTrue();
+ assertThat(mStopController.isExemptFromStopping(mediaProjection,
+ MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue();
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -261,7 +266,8 @@ public class MediaProjectionStopControllerTest {
packages.valueAt(0));
doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission(
RECORD_SENSITIVE_CONTENT, mediaProjection.packageName);
- assertThat(mStopController.isExemptFromStopping(mediaProjection)).isTrue();
+ assertThat(mStopController.isExemptFromStopping(mediaProjection,
+ MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue();
}
@Test
@@ -270,7 +276,8 @@ public class MediaProjectionStopControllerTest {
PACKAGE_NAME);
doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission(
RECORD_SENSITIVE_CONTENT, mediaProjection.packageName);
- assertThat(mStopController.isExemptFromStopping(mediaProjection)).isTrue();
+ assertThat(mStopController.isExemptFromStopping(mediaProjection,
+ MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue();
}
@Test
@@ -278,7 +285,8 @@ public class MediaProjectionStopControllerTest {
MediaProjectionManagerService.MediaProjection mediaProjection = createMediaProjection();
doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
RECORD_SENSITIVE_CONTENT, mediaProjection.packageName);
- assertThat(mStopController.isExemptFromStopping(mediaProjection)).isTrue();
+ assertThat(mStopController.isExemptFromStopping(mediaProjection,
+ MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue();
}
@Test
@@ -287,7 +295,8 @@ public class MediaProjectionStopControllerTest {
mediaProjection.notifyVirtualDisplayCreated(1);
doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission(
RECORD_SENSITIVE_CONTENT, mediaProjection.packageName);
- assertThat(mStopController.isExemptFromStopping(mediaProjection)).isFalse();
+ assertThat(mStopController.isExemptFromStopping(mediaProjection,
+ MediaProjectionStopController.STOP_REASON_UNKNOWN)).isFalse();
}
@Test
@@ -368,6 +377,36 @@ public class MediaProjectionStopControllerTest {
verify(mStopConsumer).accept(MediaProjectionStopController.STOP_REASON_CALL_END);
}
+ @Test
+ @EnableFlags(com.android.media.projection.flags.Flags.FLAG_STOP_MEDIA_PROJECTION_ON_CALL_END)
+ public void testExemptFromStopping_callEnd_callBeforeMediaProjection() throws Exception {
+ when(mTelecomManager.isInCall()).thenReturn(true);
+ mStopController.callStateChanged();
+
+ MediaProjectionManagerService.MediaProjection mediaProjection = createMediaProjection();
+ mediaProjection.notifyVirtualDisplayCreated(1);
+ doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission(
+ RECORD_SENSITIVE_CONTENT, mediaProjection.packageName);
+
+ assertThat(mStopController.isExemptFromStopping(mediaProjection,
+ MediaProjectionStopController.STOP_REASON_CALL_END)).isFalse();
+ }
+
+ @Test
+ @EnableFlags(com.android.media.projection.flags.Flags.FLAG_STOP_MEDIA_PROJECTION_ON_CALL_END)
+ public void testExemptFromStopping_callEnd_callAfterMediaProjection() throws Exception {
+ MediaProjectionManagerService.MediaProjection mediaProjection = createMediaProjection();
+ mediaProjection.notifyVirtualDisplayCreated(1);
+ doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission(
+ RECORD_SENSITIVE_CONTENT, mediaProjection.packageName);
+
+ when(mTelecomManager.isInCall()).thenReturn(true);
+ mStopController.callStateChanged();
+
+ assertThat(mStopController.isExemptFromStopping(mediaProjection,
+ MediaProjectionStopController.STOP_REASON_CALL_END)).isTrue();
+ }
+
private MediaProjectionManagerService.MediaProjection createMediaProjection()
throws NameNotFoundException {
return createMediaProjection(PACKAGE_NAME);