/*
* Copyright (C) 2015 Fastboot Mobile, LLC.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, see <http://www.gnu.org/licenses>.
*/
package com.fastbootmobile.encore.app.tv;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.support.v17.leanback.app.BackgroundManager;
import android.support.v17.leanback.app.DetailsFragment;
import android.support.v17.leanback.widget.Action;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.support.v17.leanback.widget.DetailsOverviewRow;
import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ListRowPresenter;
import android.support.v17.leanback.widget.OnActionClickedListener;
import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import android.util.DisplayMetrics;
import android.view.View;
import com.fastbootmobile.encore.app.R;
import com.fastbootmobile.encore.art.AlbumArtHelper;
import com.fastbootmobile.encore.art.AlbumArtTask;
import com.fastbootmobile.encore.art.RecyclingBitmapDrawable;
import com.fastbootmobile.encore.framework.PlaybackProxy;
import com.fastbootmobile.encore.model.Artist;
import com.fastbootmobile.encore.model.BoundEntity;
import com.fastbootmobile.encore.model.Playlist;
import com.fastbootmobile.encore.model.Song;
import com.fastbootmobile.encore.providers.ProviderAggregator;
import com.fastbootmobile.encore.service.BasePlaybackCallback;
import com.fastbootmobile.encore.utils.Utils;
import java.util.Iterator;
public class TvPlaylistDetailsFragment extends DetailsFragment {
private static final String TAG = "PlaylistDetailsFragment";
private static final int DETAIL_THUMB_WIDTH = 274;
private static final int DETAIL_THUMB_HEIGHT = 274;
private static final int ACTION_PLAY = 1;
private static final int ACTION_QUEUE = 2;
private static final int MSG_UPDATE_ADAPTER = 1;
private Playlist mPlaylist;
private ArrayObjectAdapter mAdapter;
private ClassPresenterSelector mPresenterSelector;
private SongRowPresenter mSongRowPresenter;
private BackgroundManager mBackgroundManager;
private Drawable mDefaultBackground;
private int mBackgroundColor;
private DisplayMetrics mMetrics;
private Action mActionPlay;
private Action mActionQueue;
private boolean mIsPlaying;
private Handler mHandler;
private BasePlaybackCallback mPlaybackCallback;
private View.OnClickListener mSongClickListener;
private AlbumArtTask mArtTask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_ADAPTER:
updateAdapter();
break;
}
}
};
mPlaybackCallback = new BasePlaybackCallback() {
@Override
public void onSongStarted(boolean buffering, Song s) throws RemoteException {
mSongRowPresenter.setCurrentSong(PlaybackProxy.getCurrentTrack());
mHandler.sendEmptyMessage(MSG_UPDATE_ADAPTER);
}
};
mSongClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
SongRow row = (SongRow) v.getTag();
PlaybackProxy.clearQueue();
PlaybackProxy.queuePlaylist(mPlaylist, false);
PlaybackProxy.playAtIndex(row.getPosition());
mIsPlaying = true;
mActionPlay.setLabel1(getString(R.string.pause));
updateAdapter();
}
};
mActionPlay = new Action(ACTION_PLAY, getString(R.string.play));
mActionQueue = new Action(ACTION_QUEUE, getString(R.string.tv_action_queue));
prepareBackgroundManager();
mPlaylist = getActivity().getIntent().getParcelableExtra(TvPlaylistDetailsActivity.EXTRA_PLAYLIST);
mBackgroundColor = getActivity().getIntent().getIntExtra(TvPlaylistDetailsActivity.EXTRA_COLOR, getResources().getColor(R.color.primary));
if (mPlaylist != null) {
setupAdapter();
setupDetailsOverviewRow();
setupDetailsOverviewRowPresenter();
setupTrackListRow();
setupTrackListRowPresenter();
setupFragmentBackground();
} else {
Intent intent = new Intent(getActivity(), TvActivity.class);
startActivity(intent);
}
}
@Override
public void onResume() {
super.onResume();
PlaybackProxy.addCallback(mPlaybackCallback);
mSongRowPresenter.setCurrentSong(PlaybackProxy.getCurrentTrack());
updateAdapter();
}
@Override
public void onPause() {
super.onPause();
PlaybackProxy.removeCallback(mPlaybackCallback);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mArtTask != null) {
mArtTask.cancel(true);
}
}
private void updateAdapter() {
mAdapter.notifyArrayItemRangeChanged(0, mAdapter.size());
}
private void prepareBackgroundManager() {
mBackgroundManager = BackgroundManager.getInstance(getActivity());
mBackgroundManager.attach(getActivity().getWindow());
mDefaultBackground = getResources().getDrawable(R.drawable.bg_welcome_top);
mMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics);
}
private void setupAdapter() {
mPresenterSelector = new ClassPresenterSelector();
mAdapter = new ArrayObjectAdapter(mPresenterSelector);
setAdapter(mAdapter);
}
private void setupDetailsOverviewRow() {
final Resources res = getResources();
final DetailsOverviewRow row = new DetailsOverviewRow(mPlaylist);
row.setImageDrawable(res.getDrawable(R.drawable.album_placeholder));
SparseArrayObjectAdapter actionsAdapter = new SparseArrayObjectAdapter();
actionsAdapter.set(ACTION_PLAY, mActionPlay);
actionsAdapter.set(ACTION_QUEUE, mActionQueue);
row.setActionsAdapter(actionsAdapter);
mAdapter.add(row);
AlbumArtHelper.retrieveAlbumArt(getResources(), new AlbumArtHelper.AlbumArtListener() {
@Override
public void onArtLoaded(RecyclingBitmapDrawable output, BoundEntity request) {
if (output != null) {
row.setImageDrawable(output);
updateAdapter();
}
}
}, mPlaylist, DETAIL_THUMB_WIDTH, false);
}
private void setupDetailsOverviewRowPresenter() {
// Set detail background and style.
DetailsOverviewRowPresenter detailsPresenter =
new DetailsOverviewRowPresenter(new PlaylistDetailsPresenter());
detailsPresenter.setBackgroundColor(mBackgroundColor);
detailsPresenter.setStyleLarge(false);
// Hook up transition element.
detailsPresenter.setSharedElementEnterTransition(getActivity(),
TvPlaylistDetailsActivity.SHARED_ELEMENT_NAME);
detailsPresenter.setOnActionClickedListener(new OnActionClickedListener() {
@Override
public void onActionClicked(Action action) {
if (action.getId() == ACTION_PLAY) {
if (mIsPlaying) {
PlaybackProxy.pause();
mIsPlaying = false;
} else {
PlaybackProxy.playPlaylist(mPlaylist);
mIsPlaying = true;
}
mActionPlay.setLabel1(getString(mIsPlaying ? R.string.pause : R.string.play));
updateAdapter();
} else if (action.getId() == ACTION_QUEUE) {
PlaybackProxy.queuePlaylist(mPlaylist, false);
}
}
});
mPresenterSelector.addClassPresenter(DetailsOverviewRow.class, detailsPresenter);
}
private void setupTrackListRow() {
Iterator<String> it = mPlaylist.songs();
int index = 0;
while (it.hasNext()) {
String trackRef = it.next();
Song song = ProviderAggregator.getDefault().retrieveSong(trackRef, mPlaylist.getProvider());
if (song != null) {
mAdapter.add(new SongRow(song, index++));
}
}
}
private void setupTrackListRowPresenter() {
mSongRowPresenter = new SongRowPresenter(mSongClickListener);
mPresenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter());
mPresenterSelector.addClassPresenter(SongRow.class, mSongRowPresenter);
}
private void setupFragmentBackground() {
String artistRef = Utils.getMainArtist(mPlaylist);
if (artistRef != null) {
Artist artist = ProviderAggregator.getDefault().retrieveArtist(artistRef, mPlaylist.getProvider());
mArtTask = AlbumArtHelper.retrieveAlbumArt(getResources(), new AlbumArtHelper.AlbumArtListener() {
@Override
public void onArtLoaded(RecyclingBitmapDrawable output, BoundEntity request) {
if (output != null && mBackgroundManager.isAttached()) {
mBackgroundManager.setDrawable(output);
}
}
}, artist, mMetrics.widthPixels, false);
}
}
}