org.runbuddy.tomahawk.utils.MediaPlayIntentHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.runbuddy.tomahawk.utils.MediaPlayIntentHandler.java

Source

/* == This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
 *
 *   Copyright 2016, Enno Gottschalk <mrmaffen@googlemail.com>
 *
 *   Tomahawk 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.
 *
 *   Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 */
package org.runbuddy.tomahawk.utils;

import android.app.SearchManager;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.media.session.MediaControllerCompat;

import org.jdeferred.DoneCallback;
import org.runbuddy.libtomahawk.collection.Album;
import org.runbuddy.libtomahawk.collection.Artist;
import org.runbuddy.libtomahawk.collection.Collection;
import org.runbuddy.libtomahawk.collection.CollectionManager;
import org.runbuddy.libtomahawk.collection.Playlist;
import org.runbuddy.libtomahawk.collection.StationPlaylist;
import org.runbuddy.libtomahawk.database.DatabaseHelper;
import org.runbuddy.libtomahawk.infosystem.InfoSystem;
import org.runbuddy.libtomahawk.infosystem.stations.ScriptPlaylistGenerator;
import org.runbuddy.libtomahawk.infosystem.stations.ScriptPlaylistGeneratorManager;
import org.runbuddy.libtomahawk.infosystem.stations.ScriptPlaylistGeneratorSearchResult;
import org.runbuddy.libtomahawk.resolver.PipeLine;
import org.runbuddy.libtomahawk.resolver.Query;
import org.runbuddy.libtomahawk.resolver.ResultScoring;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import de.greenrobot.event.EventBus;

public class MediaPlayIntentHandler {

    private Artist mResolvingArtist;

    private Album mResolvingAlbum;

    private String mWaitingGenre;

    private final Set<String> mCorrespondingRequestIds = Collections
            .newSetFromMap(new ConcurrentHashMap<String, Boolean>());

    private final Set<Query> mCorrespondingQueries = Collections
            .newSetFromMap(new ConcurrentHashMap<Query, Boolean>());

    private PlaybackManager mPlaybackManager;

    private MediaControllerCompat.TransportControls mTransportControls;

    @SuppressWarnings("unused")
    public void onEvent(ScriptPlaylistGeneratorManager.GeneratorAddedEvent event) {
        playGenre();
    }

    @SuppressWarnings("unused")
    public void onEvent(PipeLine.ResultsEvent event) {
        if (mCorrespondingQueries.contains(event.mQuery)) {
            Playlist playlist;
            if (event.mQuery.isFullTextQuery()) {
                playlist = event.mQuery.getResultPlaylist();
            } else {
                List<Query> queries = new ArrayList<>();
                queries.add(event.mQuery);
                playlist = Playlist.fromQueryList(event.mQuery.getCacheKey(), "", "", queries);
            }
            playPlaylist(playlist, false);
        }
    }

    @SuppressWarnings("unused")
    public void onEvent(InfoSystem.ResultsEvent event) {
        if (mCorrespondingRequestIds.contains(event.mInfoRequestData.getRequestId())) {
            if (mResolvingAlbum != null) {
                CollectionManager.get().getHatchetCollection().getAlbumTracks(mResolvingAlbum)
                        .done(new DoneCallback<Playlist>() {
                            @Override
                            public void onDone(Playlist result) {
                                if (result != null && result.size() > 0) {
                                    playPlaylist(result, false);
                                }
                            }
                        });
            } else if (mResolvingArtist != null) {
                CollectionManager.get().getHatchetCollection().getArtistTopHits(mResolvingArtist)
                        .done(new DoneCallback<Playlist>() {
                            @Override
                            public void onDone(Playlist result) {
                                if (result != null && result.size() > 0) {
                                    playPlaylist(result, false);
                                }
                            }
                        });
            }
        }
    }

    public MediaPlayIntentHandler(MediaControllerCompat.TransportControls transportControls,
            PlaybackManager playbackManager) {
        mTransportControls = transportControls;
        mPlaybackManager = playbackManager;
        EventBus.getDefault().register(this);
    }

    public void mediaPlayFromSearch(Bundle extras) {
        mWaitingGenre = null;
        mCorrespondingQueries.clear();
        mCorrespondingRequestIds.clear();
        mResolvingAlbum = null;
        mResolvingArtist = null;

        String mediaFocus = extras.getString(MediaStore.EXTRA_MEDIA_FOCUS);
        String query = extras.getString(SearchManager.QUERY);

        // Some of these extras may not be available depending on the search mode
        String album = extras.getString(MediaStore.EXTRA_MEDIA_ALBUM);
        String artist = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST);
        final String genre = extras.getString("android.intent.extra.genre");
        String playlist = extras.getString("android.intent.extra.playlist");
        String title = extras.getString(MediaStore.EXTRA_MEDIA_TITLE);
        // Determine the search mode and use the corresponding extras
        if (mediaFocus == null) {
            // 'Unstructured' search mode (backward compatible)
            Query q = Query.get(query, false);
            mCorrespondingQueries.clear();
            mCorrespondingQueries.add(PipeLine.get().resolve(q));
        } else if (mediaFocus.compareTo("vnd.android.cursor.item/*") == 0) {
            if (query != null && query.isEmpty()) {
                // 'Any' search mode
                CollectionManager.get().getUserCollection().getQueries(Collection.SORT_ALPHA)
                        .done(new DoneCallback<Playlist>() {
                            @Override
                            public void onDone(Playlist collectionTracks) {
                                playPlaylist(collectionTracks, true);
                            }
                        });
            } else {
                // 'Unstructured' search mode
                Query q = Query.get(query, false);
                mCorrespondingQueries.add(PipeLine.get().resolve(q));
            }
        } else if (mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0) {
            // 'Genre' search mode
            mWaitingGenre = genre;
            playGenre();
        } else if (mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Artist' search mode
            final Artist a = Artist.get(artist);
            CollectionManager.get().getUserCollection().getArtistTracks(a).done(new DoneCallback<Playlist>() {
                @Override
                public void onDone(Playlist result) {
                    if (result != null && result.size() > 0) {
                        // There are some local tracks for the requested artist available
                        playPlaylist(result, false);
                    } else {
                        // Try fetching top-hits for the requested artist
                        mResolvingArtist = a;
                        mCorrespondingRequestIds.add(InfoSystem.get().resolve(a, true));
                    }
                }
            });
        } else if (mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0) {
            // 'Album' search mode
            final Album a = Album.get(album, Artist.get(artist));
            CollectionManager.get().getUserCollection().getAlbumTracks(a).done(new DoneCallback<Playlist>() {
                @Override
                public void onDone(Playlist result) {
                    if (result != null && result.size() > 0) {
                        // There are some local tracks for the requested album available
                        playPlaylist(result, false);
                    } else {
                        // Try fetching top-hits for the requested album
                        mResolvingAlbum = a;
                        mCorrespondingRequestIds.add(InfoSystem.get().resolve(a));
                    }
                }
            });
        } else if (mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0) {
            // 'Song' search mode
            Query q = Query.get(title, album, artist, false);
            mCorrespondingQueries.add(PipeLine.get().resolve(q));
        } else if (mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Playlist' search mode
            Playlist bestMatch = null;
            float bestScore = 0f;
            float minScore = 0.7f;
            for (Playlist pl : DatabaseHelper.get().getPlaylists()) {
                float score = ResultScoring.calculateScore(pl.getName(), playlist);
                if (score > minScore && score > bestScore) {
                    bestMatch = pl;
                    bestScore = score;
                }
            }
            if (bestMatch != null) {
                playPlaylist(bestMatch, false);
            }
        }
    }

    private void playPlaylist(Playlist playlist, boolean shuffled) {
        mPlaybackManager.setPlaylist(playlist);
        if (shuffled) {
            mPlaybackManager.setShuffleMode(PlaybackManager.SHUFFLED);
        }
        mTransportControls.play();
        EventBus.getDefault().unregister(this);
    }

    private void playGenre() {
        ScriptPlaylistGenerator generator = ScriptPlaylistGeneratorManager.get().getDefaultPlaylistGenerator();
        if (generator != null && mWaitingGenre != null) {
            final String genre = mWaitingGenre;
            mWaitingGenre = null;
            generator.search(genre).done(new DoneCallback<ScriptPlaylistGeneratorSearchResult>() {
                @Override
                public void onDone(ScriptPlaylistGeneratorSearchResult result) {
                    if (result.mGenres.size() > 0) {
                        String bestMatch = null;
                        float bestScore = 0f;
                        float minScore = 0.7f;
                        for (String genreResult : result.mGenres) {
                            float score = ResultScoring.calculateScore(genreResult, genre.toLowerCase());
                            if (score > minScore && score > bestScore) {
                                bestMatch = genreResult;
                                bestScore = score;
                            }
                        }
                        if (bestMatch != null) {
                            List<String> list = new ArrayList<>();
                            list.add(bestMatch);
                            StationPlaylist pl = StationPlaylist.get(null, null, list);
                            playPlaylist(pl, false);
                        }
                    }
                }
            });
        }
    }

}