/*
* Copyright (C) 2014 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.torrenttunes.android.ui;
import android.content.ComponentName;
import android.media.session.PlaybackState;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.browse.MediaBrowserCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.view.View;
import com.torrenttunes.android.MusicService;
import com.torrenttunes.android.R;
import com.torrenttunes.android.utils.LogHelper;
import com.torrenttunes.android.utils.NetworkHelper;
import com.google.android.libraries.cast.companionlibrary.utils.LogUtils;
/**
* Base activity for activities that need to show a playback control fragment when media is playing.
*/
public abstract class BaseActivity extends ActionBarCastActivity implements MediaBrowserProvider, MediaControllerProvider {
private static final String TAG = LogHelper.makeLogTag(BaseActivity.class);
private MediaBrowserCompat mMediaBrowser;
private PlaybackControlsFragment mControlsFragment;
private MediaControllerCompat mMediaController;
private View mControlsContainer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LogHelper.d(TAG, "Activity onCreate");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Since our app icon has the same color as colorPrimary, our entry in the Recent Apps
// list gets weird. We need to change either the icon or the color of the TaskDescription.
//ActivityManager.TaskDescription taskDesc = new ActivityManager.TaskDescription(
// getTitle().toString(),
// BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_white),
// ResourceHelper.getThemeColor(this, R.attr.colorPrimary, android.R.color.darker_gray));
//setTaskDescription(taskDesc);
}
// Connect a media browser just to get the media session token. There are other ways
// this can be done, for example by sharing the session token directly.
mMediaBrowser = new MediaBrowserCompat(this, new ComponentName(this, MusicService.class), mMediaBrowserConnectionCallback, null);
}
@Override
protected void onStart() {
super.onStart();
LogHelper.d(TAG, "Activity onStart");
mControlsContainer = findViewById(R.id.controls_container);
mControlsFragment = (PlaybackControlsFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_playback_controls);
if (mControlsFragment == null) {
throw new IllegalStateException("Mising fragment with id 'controls'. Cannot continue.");
}
hidePlaybackControls();
if (mMediaBrowser != null) {
mMediaBrowser.connect();
}
}
@Override
protected void onStop() {
super.onStop();
LogHelper.d(TAG, "Activity onStop");
if (mMediaController != null) {
mMediaController.unregisterCallback(mMediaControllerCallback);
}
if (mMediaBrowser != null) {
mMediaBrowser.disconnect();
}
}
@Override
public MediaBrowserCompat getMediaBrowser() {
return mMediaBrowser;
}
@Override
public MediaControllerCompat getSupportMediaController() {
return mMediaController;
}
protected void onMediaControllerConnected() {
// empty implementation, can be overridden by clients.
}
protected void showPlaybackControls() {
LogHelper.d(TAG, "showPlaybackControls");
if (NetworkHelper.isOnline(this)) {
// getFragmentManager().beginTransaction()
// .setCustomAnimations(
// R.animator.slide_in_from_bottom, R.animator.slide_out_to_bottom,
// R.animator.slide_in_from_bottom, R.animator.slide_out_to_bottom)
// .show(mControlsFragment)
// .commit();
mControlsContainer.setVisibility(View.VISIBLE);
}
}
protected void hidePlaybackControls() {
LogHelper.d(TAG, "hidePlaybackControls");
// getFragmentManager().beginTransaction()
// .hide(mControlsFragment)
// .commit();
mControlsContainer.setVisibility(View.GONE);
}
/**
* Check if the MediaSession is active and in a "playback-able" state
* (not NONE and not STOPPED).
*
* @return true if the MediaSession's state requires playback controls to be visible.
*/
protected boolean shouldShowControls() {
MediaControllerCompat mediaController = mMediaController;
if (mediaController == null ||
mediaController.getMetadata() == null ||
mediaController.getPlaybackState() == null) {
return false;
}
switch (mediaController.getPlaybackState().getState()) {
case PlaybackState.STATE_ERROR:
case PlaybackState.STATE_NONE:
case PlaybackState.STATE_STOPPED:
return false;
default:
return true;
}
}
private void connectToSession(MediaSessionCompat.Token token) {
try {
LogUtils.LOGD(TAG, "Session Token: " + token);
mMediaController = new MediaControllerCompat(this, token);
mMediaController.registerCallback(mMediaControllerCallback);
if (shouldShowControls()) {
showPlaybackControls();
} else {
LogHelper.d(TAG, "connectionCallback.onConnected: " + "hiding controls because metadata is null");
hidePlaybackControls();
}
if (mControlsFragment != null) {
mControlsFragment.onConnected();
}
onMediaControllerConnected();
} catch (RemoteException ex) {
}
}
// Callback that ensures that we are showing the controls
private final MediaControllerCompat.Callback mMediaControllerCallback =
new MediaControllerCompat.Callback() {
@Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
if (shouldShowControls()) {
showPlaybackControls();
} else {
LogHelper.d(TAG, "mediaControllerCallback.onPlaybackStateChanged: " + "hiding controls because state is ",
state == null ? "null" : state.getState());
hidePlaybackControls();
}
}
@Override
public void onMetadataChanged(MediaMetadataCompat metadata) {
if (shouldShowControls()) {
showPlaybackControls();
} else {
LogHelper.d(TAG, "mediaControllerCallback.onMetadataChanged: " +
"hiding controls because metadata is null");
hidePlaybackControls();
}
}
};
private MediaBrowserCompat.ConnectionCallback mMediaBrowserConnectionCallback =
new MediaBrowserCompat.ConnectionCallback() {
@Override
public void onConnected() {
LogHelper.d(TAG, "onConnected");
MediaSessionCompat.Token token = mMediaBrowser.getSessionToken();
if (token == null) {
throw new IllegalArgumentException("No Session token");
}
connectToSession(token);
}
};
}