/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.car.cluster.sample; import static com.android.car.cluster.sample.DebugUtil.DEBUG; import android.content.Context; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.MediaSessionManager; import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener; import android.media.session.PlaybackState; import android.util.Log; import java.lang.ref.WeakReference; import java.util.List; /** * Reports current media status to instrument cluster renderer through {@link MediaStateListener} */ public class MediaStateMonitor { private final static String TAG = DebugUtil.getTag(MediaStateMonitor.class); private final Context mContext; private final MediaListener mMediaListener; private MediaController mPrimaryMediaController; private OnActiveSessionsChangedListener mActiveSessionsChangedListener; private MediaSessionManager mMediaSessionManager; private MediaStateListener mListener; public MediaStateMonitor(Context context, MediaStateListener listener) { mListener = listener; mContext = context; mMediaListener = new MediaListener(this); mActiveSessionsChangedListener = controllers -> onActiveSessionsChanged(controllers); mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class); mMediaSessionManager.addOnActiveSessionsChangedListener( mActiveSessionsChangedListener, null); onActiveSessionsChanged(mMediaSessionManager.getActiveSessions(null)); } private void onActiveSessionsChanged(List controllers) { if (DEBUG) { Log.d(TAG, "onActiveSessionsChanged, controllers found: " + controllers.size()); } MediaController newPrimaryController = null; if (!controllers.isEmpty()) { newPrimaryController = controllers.get(0); if (mPrimaryMediaController == newPrimaryController) { // Primary media controller has not been changed. return; } } releasePrimaryMediaController(); if (newPrimaryController != null) { mPrimaryMediaController = newPrimaryController; mPrimaryMediaController.registerCallback(mMediaListener); mListener.onMediaAppChanged( new MediaAppInfo(mContext, mPrimaryMediaController.getPackageName())); } updateRendererMediaStatusIfAvailable(); } public void release() { releasePrimaryMediaController(); if (mActiveSessionsChangedListener != null) { mMediaSessionManager.removeOnActiveSessionsChangedListener( mActiveSessionsChangedListener); mActiveSessionsChangedListener = null; } mMediaSessionManager = null; } private void releasePrimaryMediaController() { if (mPrimaryMediaController != null) { mPrimaryMediaController.unregisterCallback(mMediaListener); mPrimaryMediaController = null; } } private void updateRendererMediaStatusIfAvailable() { mListener.onMetadataChanged( mPrimaryMediaController == null ? null : mPrimaryMediaController.getMetadata()); mListener.onPlaybackStateChanged( mPrimaryMediaController == null ? null : mPrimaryMediaController.getPlaybackState()); } private void onPlaybackStateChanged(PlaybackState state) { mListener.onPlaybackStateChanged(state); } private void onMetadataChanged(MediaMetadata metadata) { mListener.onMetadataChanged(metadata); } public interface MediaStateListener { void onPlaybackStateChanged(PlaybackState playbackState); void onMetadataChanged(MediaMetadata metadata); void onMediaAppChanged(MediaAppInfo mediaAppPackage); } private static class MediaListener extends MediaController.Callback { private final WeakReference mServiceRef; MediaListener(MediaStateMonitor service) { mServiceRef = new WeakReference<>(service); } @Override public void onPlaybackStateChanged(PlaybackState state) { MediaStateMonitor service = mServiceRef.get(); if (service != null) { service.onPlaybackStateChanged(state); } } @Override public void onMetadataChanged(MediaMetadata metadata) { MediaStateMonitor service = mServiceRef.get(); if (service != null) { service.onMetadataChanged(metadata); } } } }