From c18512fef5f48e445a1b8395ae5f25a74e26e7b2 Mon Sep 17 00:00:00 2001 From: Sergey Nikolaienkov Date: Wed, 28 Oct 2020 10:10:15 +0000 Subject: [PATCH] Introduce PipMediaController.MetadataListener Introduce MetadataListener interface to the PipMediaController (required by .tv.PipNotification. Remove unused field mActivityManager and unused IActivityManager constructor parameter. Bug: 169575409 Bug: 165795012 Test: make WindowManager-Shell; make SystemUI Change-Id: I6988d9aa95edd6152d807300520803116f193a3b --- .../wm/shell/pip/PipMediaController.java | 74 +++++++++++++++---- .../pip/phone/PipMenuActivityController.java | 4 +- .../systemui/wmshell/WMShellBaseModule.java | 5 +- 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java index 1fa05e01b4d6d..a7c34fd4465aa 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java @@ -19,7 +19,6 @@ package com.android.wm.shell.pip; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; -import android.app.IActivityManager; import android.app.PendingIntent; import android.app.RemoteAction; import android.content.BroadcastReceiver; @@ -28,11 +27,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.drawable.Icon; +import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.os.UserHandle; +import androidx.annotation.Nullable; + import com.android.wm.shell.R; import java.util.ArrayList; @@ -61,8 +63,17 @@ public class PipMediaController { void onMediaActionsChanged(List actions); } + /** + * A listener interface to receive notification on changes to the media metadata. + */ + public interface MetadataListener { + /** + * Called when the media metadata changes. + */ + void onMediaMetadataChanged(MediaMetadata metadata); + } + private final Context mContext; - private final IActivityManager mActivityManager; private final MediaSessionManager mMediaSessionManager; private MediaController mMediaController; @@ -94,16 +105,21 @@ public class PipMediaController { public void onPlaybackStateChanged(PlaybackState state) { notifyActionsChanged(); } + + @Override + public void onMetadataChanged(@Nullable MediaMetadata metadata) { + notifyMetadataChanged(metadata); + } }; private final MediaSessionManager.OnActiveSessionsChangedListener mSessionsChangedListener = - controllers -> resolveActiveMediaController(controllers); + this::resolveActiveMediaController; - private ArrayList mListeners = new ArrayList<>(); + private final ArrayList mActionListeners = new ArrayList<>(); + private final ArrayList mMetadataListeners = new ArrayList<>(); - public PipMediaController(Context context, IActivityManager activityManager) { + public PipMediaController(Context context) { mContext = context; - mActivityManager = activityManager; IntentFilter mediaControlFilter = new IntentFilter(); mediaControlFilter.addAction(ACTION_PLAY); mediaControlFilter.addAction(ACTION_PAUSE); @@ -128,9 +144,9 @@ public class PipMediaController { /** * Adds a new media action listener. */ - public void addListener(ActionListener listener) { - if (!mListeners.contains(listener)) { - mListeners.add(listener); + public void addActionListener(ActionListener listener) { + if (!mActionListeners.contains(listener)) { + mActionListeners.add(listener); listener.onMediaActionsChanged(getMediaActions()); } } @@ -138,9 +154,31 @@ public class PipMediaController { /** * Removes a media action listener. */ - public void removeListener(ActionListener listener) { + public void removeActionListener(ActionListener listener) { listener.onMediaActionsChanged(Collections.emptyList()); - mListeners.remove(listener); + mActionListeners.remove(listener); + } + + /** + * Adds a new media metadata listener. + */ + public void addMetadataListener(MetadataListener listener) { + if (!mMetadataListeners.contains(listener)) { + mMetadataListeners.add(listener); + listener.onMediaMetadataChanged(getMediaMetadata()); + } + } + + /** + * Removes a media metadata listener. + */ + public void removeMetadataListener(MetadataListener listener) { + listener.onMediaMetadataChanged(null); + mMetadataListeners.remove(listener); + } + + private MediaMetadata getMediaMetadata() { + return mMediaController != null ? mMediaController.getMetadata() : null; } /** @@ -242,6 +280,7 @@ public class PipMediaController { controller.registerCallback(mPlaybackChangedListener); } notifyActionsChanged(); + notifyMetadataChanged(getMediaMetadata()); // TODO(winsonc): Consider if we want to close the PIP after a timeout (like on TV) } @@ -251,9 +290,18 @@ public class PipMediaController { * Notifies all listeners that the actions have changed. */ private void notifyActionsChanged() { - if (!mListeners.isEmpty()) { + if (!mActionListeners.isEmpty()) { List actions = getMediaActions(); - mListeners.forEach(l -> l.onMediaActionsChanged(actions)); + mActionListeners.forEach(l -> l.onMediaActionsChanged(actions)); + } + } + + /** + * Notifies all listeners that the metadata have changed. + */ + private void notifyMetadataChanged(MediaMetadata metadata) { + if (!mMetadataListeners.isEmpty()) { + mMetadataListeners.forEach(l -> l.onMediaMetadataChanged(metadata)); } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java index ad1b3955301d9..a87fa20a7f118 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java @@ -343,11 +343,11 @@ public class PipMenuActivityController { if (menuState == MENU_STATE_FULL) { // Once visible, start listening for media action changes. This call will trigger // the menu actions to be updated again. - mMediaController.addListener(mMediaActionListener); + mMediaController.addActionListener(mMediaActionListener); } else { // Once hidden, stop listening for media action changes. This call will trigger // the menu actions to be updated again. - mMediaController.removeListener(mMediaActionListener); + mMediaController.removeActionListener(mMediaActionListener); } try { diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index afae9406d0a5b..81f448afa13f1 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -123,9 +123,8 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides - static PipMediaController providePipMediaController(Context context, - IActivityManager activityManager) { - return new PipMediaController(context, activityManager); + static PipMediaController providePipMediaController(Context context) { + return new PipMediaController(context); } @WMSingleton