Merge changes from topic "media_delete_intent_rvc_qpr2" into rvc-qpr-dev
* changes: Notifications starting paused shall still be subject to timeout. Disable player's "Dismiss" button when notification is not dismissible. Media player attempts to dismiss notifications when players removed.
This commit is contained in:
@@ -2820,6 +2820,8 @@
|
||||
<string name="controls_media_title">Media</string>
|
||||
<!-- Explanation for closing controls associated with a specific media session [CHAR_LIMIT=NONE] -->
|
||||
<string name="controls_media_close_session">Hide the current session.</string>
|
||||
<!-- Explanation that controls associated with a specific media session are active [CHAR_LIMIT=NONE] -->
|
||||
<string name="controls_media_active_session">Current session cannot be hidden.</string>
|
||||
<!-- Label for a button that will hide media controls [CHAR_LIMIT=30] -->
|
||||
<string name="controls_media_dismiss_button">Dismiss</string>
|
||||
<!-- Label for button to resume media playback [CHAR_LIMIT=NONE] -->
|
||||
|
||||
@@ -359,7 +359,15 @@ public class MediaControlPanel {
|
||||
final MediaController controller = getController();
|
||||
mBackgroundExecutor.execute(() -> mSeekBarViewModel.updateController(controller));
|
||||
|
||||
// Guts label
|
||||
boolean isDismissible = data.isClearable();
|
||||
mViewHolder.getSettingsText().setText(isDismissible
|
||||
? R.string.controls_media_close_session
|
||||
: R.string.controls_media_active_session);
|
||||
|
||||
// Dismiss
|
||||
mViewHolder.getDismissLabel().setAlpha(isDismissible ? 1 : DISABLED_ALPHA);
|
||||
mViewHolder.getDismiss().setEnabled(isDismissible);
|
||||
mViewHolder.getDismiss().setOnClickListener(v -> {
|
||||
if (mKey != null) {
|
||||
closeGuts();
|
||||
|
||||
@@ -46,7 +46,7 @@ class MediaTimeoutListener @Inject constructor(
|
||||
/**
|
||||
* Callback representing that a media object is now expired:
|
||||
* @param token Media session unique identifier
|
||||
* @param pauseTimeuot True when expired for {@code PAUSED_MEDIA_TIMEOUT}
|
||||
* @param pauseTimeout True when expired for {@code PAUSED_MEDIA_TIMEOUT}
|
||||
*/
|
||||
lateinit var timeoutCallback: (String, Boolean) -> Unit
|
||||
|
||||
@@ -57,11 +57,10 @@ class MediaTimeoutListener @Inject constructor(
|
||||
// Having an old key means that we're migrating from/to resumption. We should update
|
||||
// the old listener to make sure that events will be dispatched to the new location.
|
||||
val migrating = oldKey != null && key != oldKey
|
||||
var wasPlaying = false
|
||||
if (migrating) {
|
||||
val reusedListener = mediaListeners.remove(oldKey)
|
||||
if (reusedListener != null) {
|
||||
wasPlaying = reusedListener.playing ?: false
|
||||
val wasPlaying = reusedListener.playing ?: false
|
||||
if (DEBUG) Log.d(TAG, "migrating key $oldKey to $key, for resumption")
|
||||
reusedListener.mediaData = data
|
||||
reusedListener.key = key
|
||||
@@ -159,9 +158,8 @@ class MediaTimeoutListener @Inject constructor(
|
||||
Log.v(TAG, "Execute timeout for $key")
|
||||
}
|
||||
timedOut = true
|
||||
if (dispatchEvents) {
|
||||
timeoutCallback(key, timedOut)
|
||||
}
|
||||
// this event is async, so it's safe even when `dispatchEvents` is false
|
||||
timeoutCallback(key, timedOut)
|
||||
}, PAUSED_MEDIA_TIMEOUT)
|
||||
} else {
|
||||
expireMediaTimeout(key, "playback started - $state, $key")
|
||||
|
||||
@@ -60,8 +60,10 @@ class PlayerViewHolder private constructor(itemView: View) {
|
||||
val action4 = itemView.requireViewById<ImageButton>(R.id.action4)
|
||||
|
||||
// Settings screen
|
||||
val settingsText = itemView.requireViewById<TextView>(R.id.remove_text)
|
||||
val cancel = itemView.requireViewById<View>(R.id.cancel)
|
||||
val dismiss = itemView.requireViewById<View>(R.id.dismiss)
|
||||
val dismiss = itemView.requireViewById<ViewGroup>(R.id.dismiss)
|
||||
val dismissLabel = dismiss.getChildAt(0)
|
||||
val settings = itemView.requireViewById<View>(R.id.settings)
|
||||
|
||||
init {
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.os.Trace;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.DeviceConfig.Properties;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@@ -52,6 +53,7 @@ import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.media.MediaData;
|
||||
import com.android.systemui.media.MediaDataManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.dagger.StatusBarModule;
|
||||
@@ -250,6 +252,24 @@ public class NotificationMediaManager implements Dumpable {
|
||||
}
|
||||
});
|
||||
|
||||
mMediaDataManager.addListener(new MediaDataManager.Listener() {
|
||||
@Override
|
||||
public void onMediaDataLoaded(@NonNull String key,
|
||||
@Nullable String oldKey, @NonNull MediaData data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaDataRemoved(@NonNull String key) {
|
||||
NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key);
|
||||
if (entry != null) {
|
||||
// TODO(b/160713608): "removing" this notification won't happen and
|
||||
// won't send the 'deleteIntent' if the notification is ongoing.
|
||||
mEntryManager.performRemoveNotification(entry.getSbn(),
|
||||
NotificationListenerService.REASON_CANCEL);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mShowCompactMediaSeekbar = "true".equals(
|
||||
DeviceConfig.getProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
|
||||
SystemUiDeviceConfigFlags.COMPACT_MEDIA_SEEKBAR_ENABLED));
|
||||
|
||||
@@ -109,9 +109,11 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
private lateinit var action2: ImageButton
|
||||
private lateinit var action3: ImageButton
|
||||
private lateinit var action4: ImageButton
|
||||
private lateinit var settingsText: TextView
|
||||
private lateinit var settings: View
|
||||
private lateinit var cancel: View
|
||||
private lateinit var dismiss: View
|
||||
private lateinit var dismiss: FrameLayout
|
||||
private lateinit var dismissLabel: View
|
||||
|
||||
private lateinit var session: MediaSession
|
||||
private val device = MediaDeviceData(true, null, DEVICE_NAME)
|
||||
@@ -168,12 +170,16 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
whenever(holder.action3).thenReturn(action3)
|
||||
action4 = ImageButton(context)
|
||||
whenever(holder.action4).thenReturn(action4)
|
||||
settingsText = TextView(context)
|
||||
whenever(holder.settingsText).thenReturn(settingsText)
|
||||
settings = View(context)
|
||||
whenever(holder.settings).thenReturn(settings)
|
||||
cancel = View(context)
|
||||
whenever(holder.cancel).thenReturn(cancel)
|
||||
dismiss = View(context)
|
||||
dismiss = FrameLayout(context)
|
||||
whenever(holder.dismiss).thenReturn(dismiss)
|
||||
dismissLabel = View(context)
|
||||
whenever(holder.dismissLabel).thenReturn(dismissLabel)
|
||||
|
||||
// Create media session
|
||||
val metadataBuilder = MediaMetadata.Builder().apply {
|
||||
@@ -327,6 +333,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
notificationKey = KEY)
|
||||
player.bind(state, mediaKey)
|
||||
|
||||
assertThat(dismiss.isEnabled).isEqualTo(true)
|
||||
dismiss.callOnClick()
|
||||
val captor = ArgumentCaptor.forClass(ActivityStarter.OnDismissAction::class.java)
|
||||
verify(keyguardDismissUtil).executeWhenUnlocked(captor.capture(), anyBoolean())
|
||||
@@ -334,4 +341,16 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
captor.value.onDismiss()
|
||||
verify(mediaDataManager).dismissMediaData(eq(mediaKey), anyLong())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dismissButtonDisabled() {
|
||||
val mediaKey = "key for dismissal"
|
||||
player.attach(holder)
|
||||
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
|
||||
emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null,
|
||||
isClearable = false, notificationKey = KEY)
|
||||
player.bind(state, mediaKey)
|
||||
|
||||
assertThat(dismiss.isEnabled).isEqualTo(false)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user