Loading core/java/android/companion/virtual/flags/flags.aconfig +0 −7 Original line number Diff line number Diff line Loading @@ -17,13 +17,6 @@ flag { bug: "305170199" } flag { namespace: "virtual_devices" name: "media_projection_keyguard_restrictions" description: "Auto-stop MP when the device locks" bug: "348335290" } flag { namespace: "virtual_devices" name: "virtual_display_insets" Loading services/core/java/com/android/server/media/projection/MediaProjectionStopController.java +21 −11 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.telecom.TelecomManager; import android.telephony.TelephonyCallback; Loading @@ -38,6 +39,7 @@ import android.view.Display; import com.android.internal.annotations.VisibleForTesting; import com.android.server.SystemConfig; import java.util.List; import java.util.function.Consumer; /** Loading @@ -60,21 +62,35 @@ public class MediaProjectionStopController { private final TelephonyManager mTelephonyManager; private final AppOpsManager mAppOpsManager; private final PackageManager mPackageManager; private final RoleManager mRoleManager; private final RoleHolderProvider mRoleHolderProvider; private final ContentResolver mContentResolver; private boolean mIsInCall; private long mLastCallStartTimeMillis; @VisibleForTesting interface RoleHolderProvider { List<String> getRoleHoldersAsUser(String roleName, UserHandle user); } public MediaProjectionStopController(Context context, Consumer<Integer> stopReasonConsumer) { this(context, stopReasonConsumer, (roleName, user) -> context.getSystemService(RoleManager.class) .getRoleHoldersAsUser(roleName, user)); } @VisibleForTesting MediaProjectionStopController(Context context, Consumer<Integer> stopReasonConsumer, RoleHolderProvider roleHolderProvider) { mStopReasonConsumer = stopReasonConsumer; mKeyguardManager = context.getSystemService(KeyguardManager.class); mTelecomManager = context.getSystemService(TelecomManager.class); mTelephonyManager = context.getSystemService(TelephonyManager.class); mAppOpsManager = context.getSystemService(AppOpsManager.class); mPackageManager = context.getPackageManager(); mRoleManager = context.getSystemService(RoleManager.class); mContentResolver = context.getContentResolver(); mRoleHolderProvider = roleHolderProvider; } /** Loading Loading @@ -146,8 +162,9 @@ public class MediaProjectionStopController { Slog.v(TAG, "Continuing MediaProjection for package with OP_PROJECT_MEDIA AppOp "); return true; } if (mRoleManager.getRoleHoldersAsUser(AssociationRequest.DEVICE_PROFILE_APP_STREAMING, projectionGrant.userHandle).contains(projectionGrant.packageName)) { if (mRoleHolderProvider.getRoleHoldersAsUser( AssociationRequest.DEVICE_PROFILE_APP_STREAMING, projectionGrant.userHandle) .contains(projectionGrant.packageName)) { Slog.v(TAG, "Continuing MediaProjection for package holding app streaming role."); return true; } Loading Loading @@ -177,10 +194,6 @@ public class MediaProjectionStopController { */ public boolean isStartForbidden( MediaProjectionManagerService.MediaProjection projectionGrant) { if (!android.companion.virtualdevice.flags.Flags.mediaProjectionKeyguardRestrictions()) { return false; } if (!mKeyguardManager.isKeyguardLocked()) { return false; } Loading @@ -194,9 +207,6 @@ public class MediaProjectionStopController { @VisibleForTesting void onKeyguardLockedStateChanged(boolean isKeyguardLocked) { if (!isKeyguardLocked) return; if (!android.companion.virtualdevice.flags.Flags.mediaProjectionKeyguardRestrictions()) { return; } mStopReasonConsumer.accept(STOP_REASON_KEYGUARD); } Loading services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java +0 −107 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; Loading @@ -53,15 +52,11 @@ import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import static org.testng.Assert.assertThrows; import android.Manifest; import android.annotation.SuppressLint; import android.app.ActivityManagerInternal; import android.app.ActivityOptions.LaunchCookie; import android.app.AppOpsManager; import android.app.Instrumentation; import android.app.KeyguardManager; import android.app.role.RoleManager; import android.companion.AssociationRequest; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; Loading @@ -76,11 +71,9 @@ import android.media.projection.StopReason; import android.os.Binder; import android.os.IBinder; import android.os.Looper; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.os.test.TestLooper; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; Loading @@ -99,7 +92,6 @@ import com.android.server.testutils.OffsettableClock; import com.android.server.wm.WindowManagerInternal; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading @@ -110,7 +102,6 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -292,8 +283,6 @@ public class MediaProjectionManagerServiceTest { assertThat(stoppedCallback2).isFalse(); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked() throws Exception { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); Loading @@ -308,8 +297,6 @@ public class MediaProjectionManagerServiceTest { assertThat(mIMediaProjectionCallback.mLatch.await(5, TimeUnit.SECONDS)).isTrue(); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_packageAllowlisted() throws NameNotFoundException { Loading @@ -325,8 +312,6 @@ public class MediaProjectionManagerServiceTest { assertThat(mService.getActiveProjectionInfo()).isNotNull(); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_AppOpMediaProjection() throws NameNotFoundException { Loading @@ -347,50 +332,6 @@ public class MediaProjectionManagerServiceTest { assertThat(mService.getActiveProjectionInfo()).isNotNull(); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_RoleHeld() { runWithRole( AssociationRequest.DEVICE_PROFILE_APP_STREAMING, () -> { try { mAppInfo.privateFlags |= PRIVATE_FLAG_PRIVILEGED; doReturn(mAppInfo) .when(mPackageManager) .getApplicationInfoAsUser( anyString(), any(ApplicationInfoFlags.class), any(UserHandle.class)); MediaProjectionManagerService.MediaProjection projection = mService.createProjectionInternal( Process.myUid(), mContext.getPackageName(), TYPE_MIRRORING, /* isPermanentGrant= */ false, UserHandle.CURRENT, DEFAULT_DISPLAY); doReturn(true).when(mKeyguardManager).isKeyguardLocked(); doReturn(PackageManager.PERMISSION_DENIED) .when(mPackageManager) .checkPermission(RECORD_SENSITIVE_CONTENT, projection.packageName); projection.start(mIMediaProjectionCallback); projection.notifyVirtualDisplayCreated(10); // The projection was started because it was allowed to capture the // keyguard. assertWithMessage("Failed to run projection") .that(mService.getActiveProjectionInfo()) .isNotNull(); } catch (NameNotFoundException e) { throw new RuntimeException(e); } }); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_screenshareProtectionsDisabled() throws NameNotFoundException { Loading @@ -416,8 +357,6 @@ public class MediaProjectionManagerServiceTest { } } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_noDisplayCreated() throws NameNotFoundException { Loading Loading @@ -509,8 +448,6 @@ public class MediaProjectionManagerServiceTest { assertThat(secondProjection).isNotEqualTo(projection); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testReuseProjection_keyguardNotLocked_startConsentDialog() throws NameNotFoundException { Loading @@ -527,8 +464,6 @@ public class MediaProjectionManagerServiceTest { verify(mContext).startActivityAsUser(any(), any()); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testReuseProjection_keyguardLocked_noConsentDialog() throws NameNotFoundException { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); Loading Loading @@ -1302,48 +1237,6 @@ public class MediaProjectionManagerServiceTest { return mService.getProjectionInternal(UID, PACKAGE_NAME); } /** * Run the provided block giving the current context's package the provided role. */ @SuppressWarnings("SameParameterValue") private void runWithRole(String role, Runnable block) { Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); String packageName = mContext.getPackageName(); UserHandle user = instrumentation.getTargetContext().getUser(); RoleManager roleManager = Objects.requireNonNull( mContext.getSystemService(RoleManager.class)); try { CountDownLatch latch = new CountDownLatch(1); instrumentation.getUiAutomation().adoptShellPermissionIdentity( Manifest.permission.MANAGE_ROLE_HOLDERS, Manifest.permission.BYPASS_ROLE_QUALIFICATION); roleManager.setBypassingRoleQualification(true); roleManager.addRoleHolderAsUser(role, packageName, /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, mContext.getMainExecutor(), success -> { if (success) { latch.countDown(); } else { Assert.fail("Couldn't set role for test (failure) " + role); } }); assertWithMessage("Couldn't set role for test (timeout) : " + role) .that(latch.await(1, TimeUnit.SECONDS)).isTrue(); block.run(); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { roleManager.removeRoleHolderAsUser(role, packageName, /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, mContext.getMainExecutor(), (aBool) -> {}); roleManager.setBypassingRoleQualification(false); instrumentation.getUiAutomation() .dropShellPermissionIdentity(); } } private static class FakeIMediaProjectionCallback extends IMediaProjectionCallback.Stub { CountDownLatch mLatch = new CountDownLatch(1); @Override Loading services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionStopControllerTest.java +11 −75 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import static android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_ import static android.view.Display.INVALID_DISPLAY; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; Loading @@ -37,13 +36,10 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.Manifest; import android.annotation.SuppressLint; import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.Instrumentation; import android.app.KeyguardManager; import android.app.role.RoleManager; import android.companion.AssociationRequest; import android.content.Context; import android.content.pm.ApplicationInfo; Loading @@ -69,7 +65,6 @@ import com.android.server.SystemConfig; import com.android.server.wm.WindowManagerInternal; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading @@ -79,9 +74,7 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.List; import java.util.function.Consumer; /** Loading Loading @@ -123,6 +116,8 @@ public class MediaProjectionStopControllerTest { private KeyguardManager mKeyguardManager; @Mock private TelecomManager mTelecomManager; @Mock private MediaProjectionStopController.RoleHolderProvider mRoleManager; private AppOpsManager mAppOpsManager; @Mock Loading @@ -145,7 +140,7 @@ public class MediaProjectionStopControllerTest { mContext.addMockSystemService(TelecomManager.class, mTelecomManager); mContext.setMockPackageManager(mPackageManager); mStopController = new MediaProjectionStopController(mContext, mStopConsumer); mStopController = new MediaProjectionStopController(mContext, mStopConsumer, mRoleManager); mService = new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector); Loading @@ -170,8 +165,6 @@ public class MediaProjectionStopControllerTest { } @Test @EnableFlags( android.companion.virtualdevice.flags.Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) public void testMediaProjectionNotRestricted() throws Exception { when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); Loading @@ -180,8 +173,6 @@ public class MediaProjectionStopControllerTest { } @Test @EnableFlags( android.companion.virtualdevice.flags.Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) public void testMediaProjectionRestricted() throws Exception { MediaProjectionManagerService.MediaProjection mediaProjection = createMediaProjection(); mediaProjection.notifyVirtualDisplayCreated(1); Loading Loading @@ -239,21 +230,13 @@ public class MediaProjectionStopControllerTest { @Test public void testExemptFromStoppingHasAppStreamingRole() throws Exception { runWithRole( AssociationRequest.DEVICE_PROFILE_APP_STREAMING, () -> { try { MediaProjectionManagerService.MediaProjection mediaProjection = createMediaProjection(); doReturn(PackageManager.PERMISSION_DENIED).when( mPackageManager).checkPermission( MediaProjectionManagerService.MediaProjection mediaProjection = createMediaProjection(); doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission( RECORD_SENSITIVE_CONTENT, mediaProjection.packageName); doReturn(List.of(mediaProjection.packageName)).when(mRoleManager).getRoleHoldersAsUser( eq(AssociationRequest.DEVICE_PROFILE_APP_STREAMING), any(UserHandle.class)); assertThat(mStopController.isExemptFromStopping(mediaProjection, MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue(); } catch (Exception e) { throw new RuntimeException(e); } }); } @Test Loading Loading @@ -316,8 +299,6 @@ public class MediaProjectionStopControllerTest { } @Test @EnableFlags( android.companion.virtualdevice.flags.Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) public void testKeyguardLockedStateChanged_unlocked() { mStopController.onKeyguardLockedStateChanged(false); Loading @@ -325,8 +306,6 @@ public class MediaProjectionStopControllerTest { } @Test @EnableFlags( android.companion.virtualdevice.flags.Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) public void testKeyguardLockedStateChanged_locked() { mStopController.onKeyguardLockedStateChanged(true); Loading Loading @@ -438,47 +417,4 @@ public class MediaProjectionStopControllerTest { MediaProjectionManager.TYPE_SCREEN_CAPTURE, false, mContext.getUser(), INVALID_DISPLAY); } /** * Run the provided block giving the current context's package the provided role. */ @SuppressWarnings("SameParameterValue") private void runWithRole(String role, Runnable block) { Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); String packageName = mContext.getPackageName(); UserHandle user = instrumentation.getTargetContext().getUser(); RoleManager roleManager = Objects.requireNonNull( mContext.getSystemService(RoleManager.class)); try { CountDownLatch latch = new CountDownLatch(1); instrumentation.getUiAutomation().adoptShellPermissionIdentity( Manifest.permission.MANAGE_ROLE_HOLDERS, Manifest.permission.BYPASS_ROLE_QUALIFICATION); roleManager.setBypassingRoleQualification(true); roleManager.addRoleHolderAsUser(role, packageName, /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, mContext.getMainExecutor(), success -> { if (success) { latch.countDown(); } else { Assert.fail("Couldn't set role for test (failure) " + role); } }); assertWithMessage("Couldn't set role for test (timeout) : " + role) .that(latch.await(1, TimeUnit.SECONDS)).isTrue(); block.run(); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { roleManager.removeRoleHolderAsUser(role, packageName, /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, mContext.getMainExecutor(), (aBool) -> { }); roleManager.setBypassingRoleQualification(false); instrumentation.getUiAutomation() .dropShellPermissionIdentity(); } } } Loading
core/java/android/companion/virtual/flags/flags.aconfig +0 −7 Original line number Diff line number Diff line Loading @@ -17,13 +17,6 @@ flag { bug: "305170199" } flag { namespace: "virtual_devices" name: "media_projection_keyguard_restrictions" description: "Auto-stop MP when the device locks" bug: "348335290" } flag { namespace: "virtual_devices" name: "virtual_display_insets" Loading
services/core/java/com/android/server/media/projection/MediaProjectionStopController.java +21 −11 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.telecom.TelecomManager; import android.telephony.TelephonyCallback; Loading @@ -38,6 +39,7 @@ import android.view.Display; import com.android.internal.annotations.VisibleForTesting; import com.android.server.SystemConfig; import java.util.List; import java.util.function.Consumer; /** Loading @@ -60,21 +62,35 @@ public class MediaProjectionStopController { private final TelephonyManager mTelephonyManager; private final AppOpsManager mAppOpsManager; private final PackageManager mPackageManager; private final RoleManager mRoleManager; private final RoleHolderProvider mRoleHolderProvider; private final ContentResolver mContentResolver; private boolean mIsInCall; private long mLastCallStartTimeMillis; @VisibleForTesting interface RoleHolderProvider { List<String> getRoleHoldersAsUser(String roleName, UserHandle user); } public MediaProjectionStopController(Context context, Consumer<Integer> stopReasonConsumer) { this(context, stopReasonConsumer, (roleName, user) -> context.getSystemService(RoleManager.class) .getRoleHoldersAsUser(roleName, user)); } @VisibleForTesting MediaProjectionStopController(Context context, Consumer<Integer> stopReasonConsumer, RoleHolderProvider roleHolderProvider) { mStopReasonConsumer = stopReasonConsumer; mKeyguardManager = context.getSystemService(KeyguardManager.class); mTelecomManager = context.getSystemService(TelecomManager.class); mTelephonyManager = context.getSystemService(TelephonyManager.class); mAppOpsManager = context.getSystemService(AppOpsManager.class); mPackageManager = context.getPackageManager(); mRoleManager = context.getSystemService(RoleManager.class); mContentResolver = context.getContentResolver(); mRoleHolderProvider = roleHolderProvider; } /** Loading Loading @@ -146,8 +162,9 @@ public class MediaProjectionStopController { Slog.v(TAG, "Continuing MediaProjection for package with OP_PROJECT_MEDIA AppOp "); return true; } if (mRoleManager.getRoleHoldersAsUser(AssociationRequest.DEVICE_PROFILE_APP_STREAMING, projectionGrant.userHandle).contains(projectionGrant.packageName)) { if (mRoleHolderProvider.getRoleHoldersAsUser( AssociationRequest.DEVICE_PROFILE_APP_STREAMING, projectionGrant.userHandle) .contains(projectionGrant.packageName)) { Slog.v(TAG, "Continuing MediaProjection for package holding app streaming role."); return true; } Loading Loading @@ -177,10 +194,6 @@ public class MediaProjectionStopController { */ public boolean isStartForbidden( MediaProjectionManagerService.MediaProjection projectionGrant) { if (!android.companion.virtualdevice.flags.Flags.mediaProjectionKeyguardRestrictions()) { return false; } if (!mKeyguardManager.isKeyguardLocked()) { return false; } Loading @@ -194,9 +207,6 @@ public class MediaProjectionStopController { @VisibleForTesting void onKeyguardLockedStateChanged(boolean isKeyguardLocked) { if (!isKeyguardLocked) return; if (!android.companion.virtualdevice.flags.Flags.mediaProjectionKeyguardRestrictions()) { return; } mStopReasonConsumer.accept(STOP_REASON_KEYGUARD); } Loading
services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java +0 −107 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; Loading @@ -53,15 +52,11 @@ import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import static org.testng.Assert.assertThrows; import android.Manifest; import android.annotation.SuppressLint; import android.app.ActivityManagerInternal; import android.app.ActivityOptions.LaunchCookie; import android.app.AppOpsManager; import android.app.Instrumentation; import android.app.KeyguardManager; import android.app.role.RoleManager; import android.companion.AssociationRequest; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; Loading @@ -76,11 +71,9 @@ import android.media.projection.StopReason; import android.os.Binder; import android.os.IBinder; import android.os.Looper; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.os.test.TestLooper; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; Loading @@ -99,7 +92,6 @@ import com.android.server.testutils.OffsettableClock; import com.android.server.wm.WindowManagerInternal; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading @@ -110,7 +102,6 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -292,8 +283,6 @@ public class MediaProjectionManagerServiceTest { assertThat(stoppedCallback2).isFalse(); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked() throws Exception { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); Loading @@ -308,8 +297,6 @@ public class MediaProjectionManagerServiceTest { assertThat(mIMediaProjectionCallback.mLatch.await(5, TimeUnit.SECONDS)).isTrue(); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_packageAllowlisted() throws NameNotFoundException { Loading @@ -325,8 +312,6 @@ public class MediaProjectionManagerServiceTest { assertThat(mService.getActiveProjectionInfo()).isNotNull(); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_AppOpMediaProjection() throws NameNotFoundException { Loading @@ -347,50 +332,6 @@ public class MediaProjectionManagerServiceTest { assertThat(mService.getActiveProjectionInfo()).isNotNull(); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_RoleHeld() { runWithRole( AssociationRequest.DEVICE_PROFILE_APP_STREAMING, () -> { try { mAppInfo.privateFlags |= PRIVATE_FLAG_PRIVILEGED; doReturn(mAppInfo) .when(mPackageManager) .getApplicationInfoAsUser( anyString(), any(ApplicationInfoFlags.class), any(UserHandle.class)); MediaProjectionManagerService.MediaProjection projection = mService.createProjectionInternal( Process.myUid(), mContext.getPackageName(), TYPE_MIRRORING, /* isPermanentGrant= */ false, UserHandle.CURRENT, DEFAULT_DISPLAY); doReturn(true).when(mKeyguardManager).isKeyguardLocked(); doReturn(PackageManager.PERMISSION_DENIED) .when(mPackageManager) .checkPermission(RECORD_SENSITIVE_CONTENT, projection.packageName); projection.start(mIMediaProjectionCallback); projection.notifyVirtualDisplayCreated(10); // The projection was started because it was allowed to capture the // keyguard. assertWithMessage("Failed to run projection") .that(mService.getActiveProjectionInfo()) .isNotNull(); } catch (NameNotFoundException e) { throw new RuntimeException(e); } }); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_screenshareProtectionsDisabled() throws NameNotFoundException { Loading @@ -416,8 +357,6 @@ public class MediaProjectionManagerServiceTest { } } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testCreateProjection_keyguardLocked_noDisplayCreated() throws NameNotFoundException { Loading Loading @@ -509,8 +448,6 @@ public class MediaProjectionManagerServiceTest { assertThat(secondProjection).isNotEqualTo(projection); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testReuseProjection_keyguardNotLocked_startConsentDialog() throws NameNotFoundException { Loading @@ -527,8 +464,6 @@ public class MediaProjectionManagerServiceTest { verify(mContext).startActivityAsUser(any(), any()); } @EnableFlags(android.companion.virtualdevice.flags .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) @Test public void testReuseProjection_keyguardLocked_noConsentDialog() throws NameNotFoundException { MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(); Loading Loading @@ -1302,48 +1237,6 @@ public class MediaProjectionManagerServiceTest { return mService.getProjectionInternal(UID, PACKAGE_NAME); } /** * Run the provided block giving the current context's package the provided role. */ @SuppressWarnings("SameParameterValue") private void runWithRole(String role, Runnable block) { Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); String packageName = mContext.getPackageName(); UserHandle user = instrumentation.getTargetContext().getUser(); RoleManager roleManager = Objects.requireNonNull( mContext.getSystemService(RoleManager.class)); try { CountDownLatch latch = new CountDownLatch(1); instrumentation.getUiAutomation().adoptShellPermissionIdentity( Manifest.permission.MANAGE_ROLE_HOLDERS, Manifest.permission.BYPASS_ROLE_QUALIFICATION); roleManager.setBypassingRoleQualification(true); roleManager.addRoleHolderAsUser(role, packageName, /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, mContext.getMainExecutor(), success -> { if (success) { latch.countDown(); } else { Assert.fail("Couldn't set role for test (failure) " + role); } }); assertWithMessage("Couldn't set role for test (timeout) : " + role) .that(latch.await(1, TimeUnit.SECONDS)).isTrue(); block.run(); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { roleManager.removeRoleHolderAsUser(role, packageName, /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, mContext.getMainExecutor(), (aBool) -> {}); roleManager.setBypassingRoleQualification(false); instrumentation.getUiAutomation() .dropShellPermissionIdentity(); } } private static class FakeIMediaProjectionCallback extends IMediaProjectionCallback.Stub { CountDownLatch mLatch = new CountDownLatch(1); @Override Loading
services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionStopControllerTest.java +11 −75 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import static android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_ import static android.view.Display.INVALID_DISPLAY; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; Loading @@ -37,13 +36,10 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.Manifest; import android.annotation.SuppressLint; import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.Instrumentation; import android.app.KeyguardManager; import android.app.role.RoleManager; import android.companion.AssociationRequest; import android.content.Context; import android.content.pm.ApplicationInfo; Loading @@ -69,7 +65,6 @@ import com.android.server.SystemConfig; import com.android.server.wm.WindowManagerInternal; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading @@ -79,9 +74,7 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.List; import java.util.function.Consumer; /** Loading Loading @@ -123,6 +116,8 @@ public class MediaProjectionStopControllerTest { private KeyguardManager mKeyguardManager; @Mock private TelecomManager mTelecomManager; @Mock private MediaProjectionStopController.RoleHolderProvider mRoleManager; private AppOpsManager mAppOpsManager; @Mock Loading @@ -145,7 +140,7 @@ public class MediaProjectionStopControllerTest { mContext.addMockSystemService(TelecomManager.class, mTelecomManager); mContext.setMockPackageManager(mPackageManager); mStopController = new MediaProjectionStopController(mContext, mStopConsumer); mStopController = new MediaProjectionStopController(mContext, mStopConsumer, mRoleManager); mService = new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector); Loading @@ -170,8 +165,6 @@ public class MediaProjectionStopControllerTest { } @Test @EnableFlags( android.companion.virtualdevice.flags.Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) public void testMediaProjectionNotRestricted() throws Exception { when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); Loading @@ -180,8 +173,6 @@ public class MediaProjectionStopControllerTest { } @Test @EnableFlags( android.companion.virtualdevice.flags.Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) public void testMediaProjectionRestricted() throws Exception { MediaProjectionManagerService.MediaProjection mediaProjection = createMediaProjection(); mediaProjection.notifyVirtualDisplayCreated(1); Loading Loading @@ -239,21 +230,13 @@ public class MediaProjectionStopControllerTest { @Test public void testExemptFromStoppingHasAppStreamingRole() throws Exception { runWithRole( AssociationRequest.DEVICE_PROFILE_APP_STREAMING, () -> { try { MediaProjectionManagerService.MediaProjection mediaProjection = createMediaProjection(); doReturn(PackageManager.PERMISSION_DENIED).when( mPackageManager).checkPermission( MediaProjectionManagerService.MediaProjection mediaProjection = createMediaProjection(); doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission( RECORD_SENSITIVE_CONTENT, mediaProjection.packageName); doReturn(List.of(mediaProjection.packageName)).when(mRoleManager).getRoleHoldersAsUser( eq(AssociationRequest.DEVICE_PROFILE_APP_STREAMING), any(UserHandle.class)); assertThat(mStopController.isExemptFromStopping(mediaProjection, MediaProjectionStopController.STOP_REASON_UNKNOWN)).isTrue(); } catch (Exception e) { throw new RuntimeException(e); } }); } @Test Loading Loading @@ -316,8 +299,6 @@ public class MediaProjectionStopControllerTest { } @Test @EnableFlags( android.companion.virtualdevice.flags.Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) public void testKeyguardLockedStateChanged_unlocked() { mStopController.onKeyguardLockedStateChanged(false); Loading @@ -325,8 +306,6 @@ public class MediaProjectionStopControllerTest { } @Test @EnableFlags( android.companion.virtualdevice.flags.Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS) public void testKeyguardLockedStateChanged_locked() { mStopController.onKeyguardLockedStateChanged(true); Loading Loading @@ -438,47 +417,4 @@ public class MediaProjectionStopControllerTest { MediaProjectionManager.TYPE_SCREEN_CAPTURE, false, mContext.getUser(), INVALID_DISPLAY); } /** * Run the provided block giving the current context's package the provided role. */ @SuppressWarnings("SameParameterValue") private void runWithRole(String role, Runnable block) { Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); String packageName = mContext.getPackageName(); UserHandle user = instrumentation.getTargetContext().getUser(); RoleManager roleManager = Objects.requireNonNull( mContext.getSystemService(RoleManager.class)); try { CountDownLatch latch = new CountDownLatch(1); instrumentation.getUiAutomation().adoptShellPermissionIdentity( Manifest.permission.MANAGE_ROLE_HOLDERS, Manifest.permission.BYPASS_ROLE_QUALIFICATION); roleManager.setBypassingRoleQualification(true); roleManager.addRoleHolderAsUser(role, packageName, /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, mContext.getMainExecutor(), success -> { if (success) { latch.countDown(); } else { Assert.fail("Couldn't set role for test (failure) " + role); } }); assertWithMessage("Couldn't set role for test (timeout) : " + role) .that(latch.await(1, TimeUnit.SECONDS)).isTrue(); block.run(); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { roleManager.removeRoleHolderAsUser(role, packageName, /* flags= */ RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, mContext.getMainExecutor(), (aBool) -> { }); roleManager.setBypassingRoleQualification(false); instrumentation.getUiAutomation() .dropShellPermissionIdentity(); } } }