Fix issues with setRemotePlaybackInfo
- Check permissions when building DecoratedMediaCustomViewStyle if it includes
the extras from this API
- Send device intent as a regular PendingIntent if it can open over lockscreen
Bug: 271846393
Test: atest NotificationManagerServiceTest MediaControlPanelTest
Test: manual using test app
Change-Id: Ida43bb4acc34d666e354c16c4344d5c5eb6b333b
Merged-In: Ida43bb4acc34d666e354c16c4344d5c5eb6b333b
(cherry picked from commit 335a3cb7b4)
This commit is contained in:
@@ -646,12 +646,15 @@ public class MediaControlPanel {
|
||||
} else {
|
||||
mLogger.logOpenOutputSwitcher(mUid, mPackageName, mInstanceId);
|
||||
if (device.getIntent() != null) {
|
||||
if (device.getIntent().isActivity()) {
|
||||
mActivityStarter.startActivity(
|
||||
device.getIntent().getIntent(), true);
|
||||
PendingIntent deviceIntent = device.getIntent();
|
||||
boolean showOverLockscreen = mKeyguardStateController.isShowing()
|
||||
&& mActivityIntentHelper.wouldPendingShowOverLockscreen(
|
||||
deviceIntent, mLockscreenUserManager.getCurrentUserId());
|
||||
if (deviceIntent.isActivity() && !showOverLockscreen) {
|
||||
mActivityStarter.postStartActivityDismissingKeyguard(deviceIntent);
|
||||
} else {
|
||||
try {
|
||||
device.getIntent().send();
|
||||
deviceIntent.send();
|
||||
} catch (PendingIntent.CanceledException e) {
|
||||
Log.e(TAG, "Device pending intent was canceled");
|
||||
}
|
||||
|
||||
@@ -2350,6 +2350,48 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun outputSwitcher_hasCustomIntent_openOverLockscreen() {
|
||||
// When the device for a media player has an intent that opens over lockscreen
|
||||
val pendingIntent = mock(PendingIntent::class.java)
|
||||
whenever(pendingIntent.isActivity).thenReturn(true)
|
||||
whenever(keyguardStateController.isShowing).thenReturn(true)
|
||||
whenever(activityIntentHelper.wouldPendingShowOverLockscreen(any(), any())).thenReturn(true)
|
||||
|
||||
val customDevice = device.copy(intent = pendingIntent)
|
||||
val dataWithDevice = mediaData.copy(device = customDevice)
|
||||
player.attachPlayer(viewHolder)
|
||||
player.bindPlayer(dataWithDevice, KEY)
|
||||
|
||||
// When the user taps on the output switcher,
|
||||
seamless.callOnClick()
|
||||
|
||||
// Then we send the pending intent as is, without modifying the original intent
|
||||
verify(pendingIntent).send()
|
||||
verify(pendingIntent, never()).getIntent()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun outputSwitcher_hasCustomIntent_requiresUnlock() {
|
||||
// When the device for a media player has an intent that cannot open over lockscreen
|
||||
val pendingIntent = mock(PendingIntent::class.java)
|
||||
whenever(pendingIntent.isActivity).thenReturn(true)
|
||||
whenever(keyguardStateController.isShowing).thenReturn(true)
|
||||
whenever(activityIntentHelper.wouldPendingShowOverLockscreen(any(), any()))
|
||||
.thenReturn(false)
|
||||
|
||||
val customDevice = device.copy(intent = pendingIntent)
|
||||
val dataWithDevice = mediaData.copy(device = customDevice)
|
||||
player.attachPlayer(viewHolder)
|
||||
player.bindPlayer(dataWithDevice, KEY)
|
||||
|
||||
// When the user taps on the output switcher,
|
||||
seamless.callOnClick()
|
||||
|
||||
// Then we request keyguard dismissal
|
||||
verify(activityStarter).postStartActivityDismissingKeyguard(eq(pendingIntent))
|
||||
}
|
||||
|
||||
private fun getScrubbingChangeListener(): SeekBarViewModel.ScrubbingChangeListener =
|
||||
withArgCaptor {
|
||||
verify(seekBarViewModel).setScrubbingChangeListener(capture())
|
||||
|
||||
@@ -6751,7 +6751,8 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
|
||||
// Ensure MediaStyle has correct permissions for remote device extras
|
||||
if (notification.isStyle(Notification.MediaStyle.class)) {
|
||||
if (notification.isStyle(Notification.MediaStyle.class)
|
||||
|| notification.isStyle(Notification.DecoratedMediaCustomViewStyle.class)) {
|
||||
int hasMediaContentControlPermission = mPackageManager.checkPermission(
|
||||
android.Manifest.permission.MEDIA_CONTENT_CONTROL, pkg, userId);
|
||||
if (hasMediaContentControlPermission != PERMISSION_GRANTED) {
|
||||
|
||||
@@ -4359,6 +4359,43 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
|
||||
assertFalse(posted.getNotification().extras
|
||||
.containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
|
||||
assertFalse(posted.getNotification().extras
|
||||
.containsKey(Notification.EXTRA_MEDIA_REMOTE_ICON));
|
||||
assertFalse(posted.getNotification().extras
|
||||
.containsKey(Notification.EXTRA_MEDIA_REMOTE_INTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomMediaStyleRemote_noPermission() throws RemoteException {
|
||||
String deviceName = "device";
|
||||
when(mPackageManager.checkPermission(
|
||||
eq(android.Manifest.permission.MEDIA_CONTENT_CONTROL), any(), anyInt()))
|
||||
.thenReturn(PERMISSION_DENIED);
|
||||
Notification.DecoratedMediaCustomViewStyle style =
|
||||
new Notification.DecoratedMediaCustomViewStyle();
|
||||
style.setRemotePlaybackInfo(deviceName, 0, null);
|
||||
Notification.Builder nb = new Notification.Builder(mContext,
|
||||
mTestNotificationChannel.getId())
|
||||
.setStyle(style);
|
||||
|
||||
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
|
||||
"testCustomMediaStyleRemoteNoPermission", mUid, 0,
|
||||
nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
|
||||
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
|
||||
|
||||
mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
|
||||
nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
|
||||
waitForIdle();
|
||||
|
||||
NotificationRecord posted = mService.findNotificationLocked(
|
||||
PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
|
||||
|
||||
assertFalse(posted.getNotification().extras
|
||||
.containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
|
||||
assertFalse(posted.getNotification().extras
|
||||
.containsKey(Notification.EXTRA_MEDIA_REMOTE_ICON));
|
||||
assertFalse(posted.getNotification().extras
|
||||
.containsKey(Notification.EXTRA_MEDIA_REMOTE_INTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user