/** * Retrieves an album from the provider, and put it in the cache * * @param ref The reference to the album * @param provider The provider from which retrieve the album * @return The album, or null if the provider says so */ public Playlist retrievePlaylist(final String ref, final ProviderIdentifier provider) { if (ref == null) { // Force get stack trace try { throw new RuntimeException(); } catch (RuntimeException e) { Log.e(TAG, "retrievePlaylist called with a null reference", e); } return null; } // Try from cache Playlist output = mCache.getPlaylist(ref); if (output == null && provider != null) { ProviderConnection pc = PluginsLookup.getDefault().getProvider(provider); if (pc != null) { IMusicProvider binder = pc.getBinder(); if (binder != null) { try { output = binder.getPlaylist(ref); onPlaylistAddedOrUpdated(provider, output); } catch (RemoteException e) { Log.e(TAG, "Unable to retrieve the playlist", e); } } } } return output; }
/** * Retrieves an album from the provider, and put it in the cache * * @param ref The reference to the album * @param provider The provider from which retrieve the album * @return The album, or null if the provider says so */ public Album retrieveAlbum(final String ref, final ProviderIdentifier provider) { if (ref == null) { // Force get stack trace try { throw new RuntimeException(); } catch (RuntimeException e) { Log.e(TAG, "retrieveAlbum called with a null reference", e); } return null; } // Try from cache Album output = mCache.getAlbum(ref); if (output == null && provider != null) { ProviderConnection pc = PluginsLookup.getDefault().getProvider(provider); if (pc != null) { IMusicProvider binder = pc.getBinder(); if (binder != null) { try { output = binder.getAlbum(ref); onAlbumUpdate(provider, output); } catch (DeadObjectException e) { Log.e(TAG, "Provider died while retrieving album"); } catch (RemoteException e) { Log.e(TAG, "Unable to retrieve the album", e); } } } } return output; }
/** * Starts a search. Results will be given in onSearchResults * * @param query The terms to look for */ public void startSearch(final String query) { List<ProviderConnection> providers = PluginsLookup.getDefault().getAvailableProviders(); for (ProviderConnection providerConnection : providers) { try { final IMusicProvider binder = providerConnection.getBinder(); if (binder != null) { binder.startSearch(query); } else { Log.e(TAG, "Null binder, cannot search on " + providerConnection.getIdentifier()); } } catch (RemoteException e) { Log.e(TAG, "Cannot run search on a provider", e); } } }
/** * Retrieves a song from the provider, and put it in the cache * * @param ref The reference to the song * @param provider The provider from which retrieve the song (may be null to query cache only) * @return The song, or null if the provider says so */ public Song retrieveSong(final String ref, final ProviderIdentifier provider) { if (ref == null) { // Force get stack trace try { throw new RuntimeException(); } catch (RuntimeException e) { Log.e(TAG, "retrieveSong called with a null reference", e); } return null; } // Try from cache Song output = mCache.getSong(ref); if (output == null && provider != null) { // Get from provider then ProviderConnection pc = PluginsLookup.getDefault().getProvider(provider); if (pc != null) { IMusicProvider binder = pc.getBinder(); if (binder != null) { try { output = binder.getSong(ref); if (output != null) { onSongUpdate(provider, output); } } catch (DeadObjectException e) { Log.e(TAG, "Provider died while retrieving song"); return null; } catch (RemoteException e) { Log.e(TAG, "Unable to retrieve the song", e); return null; } } else { if (DEBUG) Log.e(TAG, "Binder null: provider not yet connected?"); } } else { Log.e(TAG, "Unknown provider identifier: " + provider); } } if (output == null && provider != null) { Log.d(TAG, "Unable to get song " + ref + " from " + provider.mName); } return output; }
@Override public void run() { // We make a copy to avoid synchronization issues and needless locks ArrayList<ProviderConnection> providers; synchronized (mProviders) { providers = new ArrayList<>(mProviders); } // Then we query the providers for (ProviderConnection conn : providers) { try { IMusicProvider binder = conn.getBinder(); if (binder != null && binder.isSetup() && binder.isAuthenticated()) { List<Playlist> playlist = binder.getPlaylists(); ensurePlaylistsSongsCached(conn, playlist); // Cache all songs in batch int offset = 0; int limit = 100; boolean goForIt = true; while (goForIt) { try { List<Song> songs = binder.getSongs(offset, limit); if (songs == null || songs.size() == 0) { goForIt = false; } else { cacheSongs(conn, songs); if (songs.size() < limit) { goForIt = false; } offset += limit; } } catch (TransactionTooLargeException ignore) { limit -= 10; Log.w(TAG, "Got transaction size error, reducing limit to " + limit); } } cacheAlbums(conn, binder.getAlbums()); cacheArtists(conn, binder.getArtists()); } else if (conn.getBinder() != null) { Log.i( TAG, "Skipping a providers because it is not setup or authenticated" + " ==> binder=" + binder + " ; isSetup=" + binder.isSetup() + " ; isAuthenticated=" + binder.isAuthenticated()); } else { unregisterProvider(conn); } } catch (RemoteException e) { Log.e(TAG, "Unable to get data from " + conn.getProviderName(), e); unregisterProvider(conn); } } }