197a60d9d00240949b9642c28a34be118469eb727Winson Chung/* 297a60d9d00240949b9642c28a34be118469eb727Winson Chung * Copyright (C) 2017 The Android Open Source Project 397a60d9d00240949b9642c28a34be118469eb727Winson Chung * 497a60d9d00240949b9642c28a34be118469eb727Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 597a60d9d00240949b9642c28a34be118469eb727Winson Chung * you may not use this file except in compliance with the License. 697a60d9d00240949b9642c28a34be118469eb727Winson Chung * You may obtain a copy of the License at 797a60d9d00240949b9642c28a34be118469eb727Winson Chung * 897a60d9d00240949b9642c28a34be118469eb727Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 997a60d9d00240949b9642c28a34be118469eb727Winson Chung * 1097a60d9d00240949b9642c28a34be118469eb727Winson Chung * Unless required by applicable law or agreed to in writing, software 1197a60d9d00240949b9642c28a34be118469eb727Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 1297a60d9d00240949b9642c28a34be118469eb727Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1397a60d9d00240949b9642c28a34be118469eb727Winson Chung * See the License for the specific language governing permissions and 1497a60d9d00240949b9642c28a34be118469eb727Winson Chung * limitations under the License. 1597a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 1697a60d9d00240949b9642c28a34be118469eb727Winson Chung 1797a60d9d00240949b9642c28a34be118469eb727Winson Chungpackage com.android.systemui.pip.phone; 1897a60d9d00240949b9642c28a34be118469eb727Winson Chung 199c2a6867578142b3e51fa8787a39d350c147b4faWinson Chungimport static android.app.PendingIntent.FLAG_UPDATE_CURRENT; 209c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung 2197a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.app.IActivityManager; 229c2a6867578142b3e51fa8787a39d350c147b4faWinson Chungimport android.app.PendingIntent; 2397a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.app.RemoteAction; 249c2a6867578142b3e51fa8787a39d350c147b4faWinson Chungimport android.content.BroadcastReceiver; 2597a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.content.ComponentName; 2697a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.content.Context; 279c2a6867578142b3e51fa8787a39d350c147b4faWinson Chungimport android.content.Intent; 289c2a6867578142b3e51fa8787a39d350c147b4faWinson Chungimport android.content.IntentFilter; 2997a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.graphics.drawable.Icon; 3097a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.media.session.MediaController; 3197a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.media.session.MediaSession; 3297a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.media.session.MediaSessionManager; 3397a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.media.session.PlaybackState; 349c2a6867578142b3e51fa8787a39d350c147b4faWinson Chungimport android.os.UserHandle; 3597a60d9d00240949b9642c28a34be118469eb727Winson Chung 3697a60d9d00240949b9642c28a34be118469eb727Winson Chungimport com.android.systemui.R; 3797a60d9d00240949b9642c28a34be118469eb727Winson Chung 3897a60d9d00240949b9642c28a34be118469eb727Winson Chungimport java.util.ArrayList; 3997a60d9d00240949b9642c28a34be118469eb727Winson Chungimport java.util.Collections; 4097a60d9d00240949b9642c28a34be118469eb727Winson Chungimport java.util.List; 4197a60d9d00240949b9642c28a34be118469eb727Winson Chung 4297a60d9d00240949b9642c28a34be118469eb727Winson Chung/** 4397a60d9d00240949b9642c28a34be118469eb727Winson Chung * Interfaces with the {@link MediaSessionManager} to compose the right set of actions to show (only 4497a60d9d00240949b9642c28a34be118469eb727Winson Chung * if there are no actions from the PiP activity itself). The active media controller is only set 4597a60d9d00240949b9642c28a34be118469eb727Winson Chung * when there is a media session from the top PiP activity. 4697a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 4797a60d9d00240949b9642c28a34be118469eb727Winson Chungpublic class PipMediaController { 4897a60d9d00240949b9642c28a34be118469eb727Winson Chung 499c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung private static final String ACTION_PLAY = "com.android.systemui.pip.phone.PLAY"; 509c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung private static final String ACTION_PAUSE = "com.android.systemui.pip.phone.PAUSE"; 5183fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung private static final String ACTION_NEXT = "com.android.systemui.pip.phone.NEXT"; 5283fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung private static final String ACTION_PREV = "com.android.systemui.pip.phone.PREV"; 539c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung 5497a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 5597a60d9d00240949b9642c28a34be118469eb727Winson Chung * A listener interface to receive notification on changes to the media actions. 5697a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 5797a60d9d00240949b9642c28a34be118469eb727Winson Chung public interface ActionListener { 5897a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 5997a60d9d00240949b9642c28a34be118469eb727Winson Chung * Called when the media actions changes. 6097a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 6197a60d9d00240949b9642c28a34be118469eb727Winson Chung void onMediaActionsChanged(List<RemoteAction> actions); 6297a60d9d00240949b9642c28a34be118469eb727Winson Chung } 6397a60d9d00240949b9642c28a34be118469eb727Winson Chung 6497a60d9d00240949b9642c28a34be118469eb727Winson Chung private final Context mContext; 6597a60d9d00240949b9642c28a34be118469eb727Winson Chung private final IActivityManager mActivityManager; 6697a60d9d00240949b9642c28a34be118469eb727Winson Chung 6797a60d9d00240949b9642c28a34be118469eb727Winson Chung private final MediaSessionManager mMediaSessionManager; 6897a60d9d00240949b9642c28a34be118469eb727Winson Chung private MediaController mMediaController; 6997a60d9d00240949b9642c28a34be118469eb727Winson Chung 7097a60d9d00240949b9642c28a34be118469eb727Winson Chung private RemoteAction mPauseAction; 7197a60d9d00240949b9642c28a34be118469eb727Winson Chung private RemoteAction mPlayAction; 7283fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung private RemoteAction mNextAction; 7383fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung private RemoteAction mPrevAction; 7497a60d9d00240949b9642c28a34be118469eb727Winson Chung 759c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung private BroadcastReceiver mPlayPauseActionReceiver = new BroadcastReceiver() { 769c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung @Override 779c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung public void onReceive(Context context, Intent intent) { 789c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung final String action = intent.getAction(); 799c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung if (action.equals(ACTION_PLAY)) { 809c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung mMediaController.getTransportControls().play(); 819c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung } else if (action.equals(ACTION_PAUSE)) { 829c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung mMediaController.getTransportControls().pause(); 8383fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung } else if (action.equals(ACTION_NEXT)) { 8483fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mMediaController.getTransportControls().skipToNext(); 8583fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung } else if (action.equals(ACTION_PREV)) { 8683fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mMediaController.getTransportControls().skipToPrevious(); 879c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung } 889c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung } 899c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung }; 909c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung 9197a60d9d00240949b9642c28a34be118469eb727Winson Chung private MediaController.Callback mPlaybackChangedListener = new MediaController.Callback() { 9297a60d9d00240949b9642c28a34be118469eb727Winson Chung @Override 9397a60d9d00240949b9642c28a34be118469eb727Winson Chung public void onPlaybackStateChanged(PlaybackState state) { 94b0103abff787f0e46ba7cf6dee877012b731565bWinson Chung notifyActionsChanged(); 9597a60d9d00240949b9642c28a34be118469eb727Winson Chung } 9697a60d9d00240949b9642c28a34be118469eb727Winson Chung }; 9797a60d9d00240949b9642c28a34be118469eb727Winson Chung 9897a60d9d00240949b9642c28a34be118469eb727Winson Chung private ArrayList<ActionListener> mListeners = new ArrayList<>(); 9997a60d9d00240949b9642c28a34be118469eb727Winson Chung 10097a60d9d00240949b9642c28a34be118469eb727Winson Chung public PipMediaController(Context context, IActivityManager activityManager) { 10197a60d9d00240949b9642c28a34be118469eb727Winson Chung mContext = context; 10297a60d9d00240949b9642c28a34be118469eb727Winson Chung mActivityManager = activityManager; 1039c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung IntentFilter mediaControlFilter = new IntentFilter(); 1049c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung mediaControlFilter.addAction(ACTION_PLAY); 1059c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung mediaControlFilter.addAction(ACTION_PAUSE); 10683fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mediaControlFilter.addAction(ACTION_NEXT); 10783fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mediaControlFilter.addAction(ACTION_PREV); 1089c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung mContext.registerReceiver(mPlayPauseActionReceiver, mediaControlFilter); 10997a60d9d00240949b9642c28a34be118469eb727Winson Chung 11097a60d9d00240949b9642c28a34be118469eb727Winson Chung createMediaActions(); 11197a60d9d00240949b9642c28a34be118469eb727Winson Chung mMediaSessionManager = 11297a60d9d00240949b9642c28a34be118469eb727Winson Chung (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE); 11397a60d9d00240949b9642c28a34be118469eb727Winson Chung mMediaSessionManager.addOnActiveSessionsChangedListener(controllers -> { 11497a60d9d00240949b9642c28a34be118469eb727Winson Chung resolveActiveMediaController(controllers); 11597a60d9d00240949b9642c28a34be118469eb727Winson Chung }, null); 11697a60d9d00240949b9642c28a34be118469eb727Winson Chung } 11797a60d9d00240949b9642c28a34be118469eb727Winson Chung 11897a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 11997a60d9d00240949b9642c28a34be118469eb727Winson Chung * Handles when an activity is pinned. 12097a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 12197a60d9d00240949b9642c28a34be118469eb727Winson Chung public void onActivityPinned() { 12297a60d9d00240949b9642c28a34be118469eb727Winson Chung // Once we enter PiP, try to find the active media controller for the top most activity 12397a60d9d00240949b9642c28a34be118469eb727Winson Chung resolveActiveMediaController(mMediaSessionManager.getActiveSessions(null)); 12497a60d9d00240949b9642c28a34be118469eb727Winson Chung } 12597a60d9d00240949b9642c28a34be118469eb727Winson Chung 12697a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 12797a60d9d00240949b9642c28a34be118469eb727Winson Chung * Adds a new media action listener. 12897a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 12997a60d9d00240949b9642c28a34be118469eb727Winson Chung public void addListener(ActionListener listener) { 13097a60d9d00240949b9642c28a34be118469eb727Winson Chung if (!mListeners.contains(listener)) { 13197a60d9d00240949b9642c28a34be118469eb727Winson Chung mListeners.add(listener); 13297a60d9d00240949b9642c28a34be118469eb727Winson Chung listener.onMediaActionsChanged(getMediaActions()); 13397a60d9d00240949b9642c28a34be118469eb727Winson Chung } 13497a60d9d00240949b9642c28a34be118469eb727Winson Chung } 13597a60d9d00240949b9642c28a34be118469eb727Winson Chung 13697a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 13797a60d9d00240949b9642c28a34be118469eb727Winson Chung * Removes a media action listener. 13897a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 13997a60d9d00240949b9642c28a34be118469eb727Winson Chung public void removeListener(ActionListener listener) { 14097a60d9d00240949b9642c28a34be118469eb727Winson Chung listener.onMediaActionsChanged(Collections.EMPTY_LIST); 14197a60d9d00240949b9642c28a34be118469eb727Winson Chung mListeners.remove(listener); 14297a60d9d00240949b9642c28a34be118469eb727Winson Chung } 14397a60d9d00240949b9642c28a34be118469eb727Winson Chung 14497a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 14597a60d9d00240949b9642c28a34be118469eb727Winson Chung * Gets the set of media actions currently available. 14697a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 14797a60d9d00240949b9642c28a34be118469eb727Winson Chung private List<RemoteAction> getMediaActions() { 14897a60d9d00240949b9642c28a34be118469eb727Winson Chung if (mMediaController == null || mMediaController.getPlaybackState() == null) { 14997a60d9d00240949b9642c28a34be118469eb727Winson Chung return Collections.EMPTY_LIST; 15097a60d9d00240949b9642c28a34be118469eb727Winson Chung } 15197a60d9d00240949b9642c28a34be118469eb727Winson Chung 15297a60d9d00240949b9642c28a34be118469eb727Winson Chung ArrayList<RemoteAction> mediaActions = new ArrayList<>(); 15397a60d9d00240949b9642c28a34be118469eb727Winson Chung int state = mMediaController.getPlaybackState().getState(); 15497a60d9d00240949b9642c28a34be118469eb727Winson Chung boolean isPlaying = MediaSession.isActiveState(state); 15597a60d9d00240949b9642c28a34be118469eb727Winson Chung long actions = mMediaController.getPlaybackState().getActions(); 15683fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung 15783fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung // Prev action 15883fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mPrevAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0); 15983fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mediaActions.add(mPrevAction); 16083fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung 16183fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung // Play/pause action 16297a60d9d00240949b9642c28a34be118469eb727Winson Chung if (!isPlaying && ((actions & PlaybackState.ACTION_PLAY) != 0)) { 16397a60d9d00240949b9642c28a34be118469eb727Winson Chung mediaActions.add(mPlayAction); 164b0103abff787f0e46ba7cf6dee877012b731565bWinson Chung } else if (isPlaying && ((actions & PlaybackState.ACTION_PAUSE) != 0)) { 165b0103abff787f0e46ba7cf6dee877012b731565bWinson Chung mediaActions.add(mPauseAction); 16697a60d9d00240949b9642c28a34be118469eb727Winson Chung } 16783fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung 16883fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung // Next action 16983fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mNextAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0); 17083fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mediaActions.add(mNextAction); 17197a60d9d00240949b9642c28a34be118469eb727Winson Chung return mediaActions; 17297a60d9d00240949b9642c28a34be118469eb727Winson Chung } 17397a60d9d00240949b9642c28a34be118469eb727Winson Chung 17497a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 17597a60d9d00240949b9642c28a34be118469eb727Winson Chung * Creates the standard media buttons that we may show. 17697a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 17797a60d9d00240949b9642c28a34be118469eb727Winson Chung private void createMediaActions() { 17897a60d9d00240949b9642c28a34be118469eb727Winson Chung String pauseDescription = mContext.getString(R.string.pip_pause); 17997a60d9d00240949b9642c28a34be118469eb727Winson Chung mPauseAction = new RemoteAction(Icon.createWithResource(mContext, 18083fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung R.drawable.ic_pause_white), pauseDescription, pauseDescription, 1819c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PAUSE), 1829c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung FLAG_UPDATE_CURRENT)); 18397a60d9d00240949b9642c28a34be118469eb727Winson Chung 18497a60d9d00240949b9642c28a34be118469eb727Winson Chung String playDescription = mContext.getString(R.string.pip_play); 18597a60d9d00240949b9642c28a34be118469eb727Winson Chung mPlayAction = new RemoteAction(Icon.createWithResource(mContext, 18683fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung R.drawable.ic_play_arrow_white), playDescription, playDescription, 1879c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PLAY), 1889c2a6867578142b3e51fa8787a39d350c147b4faWinson Chung FLAG_UPDATE_CURRENT)); 18983fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung 19083fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung String nextDescription = mContext.getString(R.string.pip_skip_to_next); 19183fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mNextAction = new RemoteAction(Icon.createWithResource(mContext, 19283fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung R.drawable.ic_skip_next_white), nextDescription, nextDescription, 19383fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NEXT), 19483fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung FLAG_UPDATE_CURRENT)); 19583fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung 19683fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung String prevDescription = mContext.getString(R.string.pip_skip_to_prev); 19783fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung mPrevAction = new RemoteAction(Icon.createWithResource(mContext, 19883fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung R.drawable.ic_skip_previous_white), prevDescription, prevDescription, 19983fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PREV), 20083fbf18ced2a386dff5fd9bb30fa5d8229cb517aWinson Chung FLAG_UPDATE_CURRENT)); 20197a60d9d00240949b9642c28a34be118469eb727Winson Chung } 20297a60d9d00240949b9642c28a34be118469eb727Winson Chung 20397a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 20497a60d9d00240949b9642c28a34be118469eb727Winson Chung * Tries to find and set the active media controller for the top PiP activity. 20597a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 20697a60d9d00240949b9642c28a34be118469eb727Winson Chung private void resolveActiveMediaController(List<MediaController> controllers) { 20797a60d9d00240949b9642c28a34be118469eb727Winson Chung if (controllers != null) { 208734c9c055657c22e2019ca77214e496442e0c52eWinson Chung final ComponentName topActivity = PipUtils.getTopPinnedActivity(mContext, 209734c9c055657c22e2019ca77214e496442e0c52eWinson Chung mActivityManager); 21097a60d9d00240949b9642c28a34be118469eb727Winson Chung if (topActivity != null) { 21197a60d9d00240949b9642c28a34be118469eb727Winson Chung for (int i = 0; i < controllers.size(); i++) { 21297a60d9d00240949b9642c28a34be118469eb727Winson Chung final MediaController controller = controllers.get(i); 21397a60d9d00240949b9642c28a34be118469eb727Winson Chung if (controller.getPackageName().equals(topActivity.getPackageName())) { 21497a60d9d00240949b9642c28a34be118469eb727Winson Chung setActiveMediaController(controller); 21597a60d9d00240949b9642c28a34be118469eb727Winson Chung return; 21697a60d9d00240949b9642c28a34be118469eb727Winson Chung } 21797a60d9d00240949b9642c28a34be118469eb727Winson Chung } 21897a60d9d00240949b9642c28a34be118469eb727Winson Chung } 21997a60d9d00240949b9642c28a34be118469eb727Winson Chung } 22097a60d9d00240949b9642c28a34be118469eb727Winson Chung setActiveMediaController(null); 22197a60d9d00240949b9642c28a34be118469eb727Winson Chung } 22297a60d9d00240949b9642c28a34be118469eb727Winson Chung 22397a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 22497a60d9d00240949b9642c28a34be118469eb727Winson Chung * Sets the active media controller for the top PiP activity. 22597a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 22697a60d9d00240949b9642c28a34be118469eb727Winson Chung private void setActiveMediaController(MediaController controller) { 22797a60d9d00240949b9642c28a34be118469eb727Winson Chung if (controller != mMediaController) { 22897a60d9d00240949b9642c28a34be118469eb727Winson Chung if (mMediaController != null) { 22997a60d9d00240949b9642c28a34be118469eb727Winson Chung mMediaController.unregisterCallback(mPlaybackChangedListener); 23097a60d9d00240949b9642c28a34be118469eb727Winson Chung } 23197a60d9d00240949b9642c28a34be118469eb727Winson Chung mMediaController = controller; 23297a60d9d00240949b9642c28a34be118469eb727Winson Chung if (controller != null) { 23397a60d9d00240949b9642c28a34be118469eb727Winson Chung controller.registerCallback(mPlaybackChangedListener); 23497a60d9d00240949b9642c28a34be118469eb727Winson Chung } 235b0103abff787f0e46ba7cf6dee877012b731565bWinson Chung notifyActionsChanged(); 23697a60d9d00240949b9642c28a34be118469eb727Winson Chung 23797a60d9d00240949b9642c28a34be118469eb727Winson Chung // TODO(winsonc): Consider if we want to close the PIP after a timeout (like on TV) 23897a60d9d00240949b9642c28a34be118469eb727Winson Chung } 23997a60d9d00240949b9642c28a34be118469eb727Winson Chung } 24097a60d9d00240949b9642c28a34be118469eb727Winson Chung 24197a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 24297a60d9d00240949b9642c28a34be118469eb727Winson Chung * Notifies all listeners that the actions have changed. 24397a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 244b0103abff787f0e46ba7cf6dee877012b731565bWinson Chung private void notifyActionsChanged() { 24597a60d9d00240949b9642c28a34be118469eb727Winson Chung if (!mListeners.isEmpty()) { 246b0103abff787f0e46ba7cf6dee877012b731565bWinson Chung List<RemoteAction> actions = getMediaActions(); 24797a60d9d00240949b9642c28a34be118469eb727Winson Chung mListeners.forEach(l -> l.onMediaActionsChanged(actions)); 24897a60d9d00240949b9642c28a34be118469eb727Winson Chung } 24997a60d9d00240949b9642c28a34be118469eb727Winson Chung } 25097a60d9d00240949b9642c28a34be118469eb727Winson Chung} 251