/** * 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; }
/** * Called by the providers when a Playlist has been added or updated. The app's providers * syndicator will automatically update the local cache of playlists based on the playlist name. */ @Override public void onPlaylistAddedOrUpdated(final ProviderIdentifier provider, final Playlist p) throws RemoteException { if (p == null || p.getRef() == null) { Log.w(TAG, "Provider returned a null playlist or a null-ref playlist"); return; } try { // We compare the provided copy with the one we have in cache. We only notify the callbacks // if it indeed changed. Playlist cached = mCache.getPlaylist(p.getRef()); boolean notify; if (cached == null) { mCache.putPlaylist(provider, p); cached = p; notify = true; } else { notify = !cached.isIdentical(p); // If the playlist isn't identical, update it if (notify) { // Update the name cached.setName(p.getName()); if (p.getName() == null) { Log.w(TAG, "Playlist " + p.getRef() + " updated, but name is null!"); } cached.setIsLoaded(p.isLoaded()); // Empty the playlist while (cached.getSongsCount() > 0) { cached.removeSong(0); } // Re-add the songs to it Iterator<String> songIt = p.songs(); while (songIt.hasNext()) { cached.addSong(songIt.next()); } // Set offline information cached.setOfflineCapable(p.isOfflineCapable()); cached.setOfflineStatus(p.getOfflineStatus()); } } final Playlist finalCachedPlaylist = cached; // If something has actually changed if (notify) { mExecutor.execute( new Runnable() { @Override public void run() { // First, we try to check if we need information for some of the songs // TODO(xplodwild): Is this really needed in a properly designed provider? Iterator<String> it = finalCachedPlaylist.songs(); while (it.hasNext()) { String ref = it.next(); retrieveSong(ref, provider); } // Then we notify the callbacks postPlaylistForUpdate(finalCachedPlaylist); } }); } } catch (Exception e) { Log.e(TAG, "FUUUU", e); } }