729 lines
24 KiB
Java
729 lines
24 KiB
Java
/*
|
|
* Copyright 2018 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.android.pump.db;
|
|
|
|
import android.Manifest;
|
|
import android.content.ContentResolver;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.RequiresPermission;
|
|
import androidx.annotation.UiThread;
|
|
import androidx.collection.ArraySet;
|
|
|
|
import com.android.pump.concurrent.Executors;
|
|
import com.android.pump.util.Clog;
|
|
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.concurrent.Executor;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
@UiThread
|
|
public class MediaDb implements MediaProvider {
|
|
private static final String TAG = Clog.tag(MediaDb.class);
|
|
|
|
private final AtomicBoolean mLoaded = new AtomicBoolean();
|
|
|
|
private final Executor mExecutor;
|
|
|
|
private final AudioStore mAudioStore;
|
|
private final VideoStore mVideoStore;
|
|
private final DataProvider mDataProvider;
|
|
|
|
private final List<Audio> mAudios = new ArrayList<>();
|
|
private final List<Artist> mArtists = new ArrayList<>();
|
|
private final List<Album> mAlbums = new ArrayList<>();
|
|
private final List<Genre> mGenres = new ArrayList<>();
|
|
private final List<Playlist> mPlaylists = new ArrayList<>();
|
|
|
|
private final List<Movie> mMovies = new ArrayList<>();
|
|
private final List<Series> mSeries = new ArrayList<>();
|
|
private final List<Episode> mEpisodes = new ArrayList<>();
|
|
private final List<Other> mOthers = new ArrayList<>();
|
|
|
|
private final Set<UpdateCallback> mAudioUpdateCallbacks = new ArraySet<>();
|
|
private final Set<UpdateCallback> mArtistUpdateCallbacks = new ArraySet<>();
|
|
private final Set<UpdateCallback> mAlbumUpdateCallbacks = new ArraySet<>();
|
|
private final Set<UpdateCallback> mGenreUpdateCallbacks = new ArraySet<>();
|
|
private final Set<UpdateCallback> mPlaylistUpdateCallbacks = new ArraySet<>();
|
|
|
|
private final Set<UpdateCallback> mMovieUpdateCallbacks = new ArraySet<>();
|
|
private final Set<UpdateCallback> mSeriesUpdateCallbacks = new ArraySet<>();
|
|
private final Set<UpdateCallback> mEpisodeUpdateCallbacks = new ArraySet<>();
|
|
private final Set<UpdateCallback> mOtherUpdateCallbacks = new ArraySet<>();
|
|
|
|
public interface UpdateCallback {
|
|
void onItemsInserted(int index, int count);
|
|
void onItemsUpdated(int index, int count);
|
|
void onItemsRemoved(int index, int count);
|
|
}
|
|
|
|
public MediaDb(@NonNull ContentResolver contentResolver, @NonNull DataProvider dataProvider,
|
|
@NonNull Executor executor) {
|
|
Clog.i(TAG, "MediaDb(" + contentResolver + ", " + dataProvider + ", " + executor + ")");
|
|
mDataProvider = dataProvider;
|
|
mExecutor = executor;
|
|
|
|
mAudioStore = new AudioStore(contentResolver, new AudioStore.ChangeListener() {
|
|
@Override
|
|
public void onAudiosAdded(@NonNull Collection<Audio> audios) {
|
|
Executors.uiThreadExecutor().execute(() -> addAudios(audios));
|
|
}
|
|
|
|
@Override
|
|
public void onArtistsAdded(@NonNull Collection<Artist> artists) {
|
|
Executors.uiThreadExecutor().execute(() -> addArtists(artists));
|
|
}
|
|
|
|
@Override
|
|
public void onAlbumsAdded(@NonNull Collection<Album> albums) {
|
|
Executors.uiThreadExecutor().execute(() -> addAlbums(albums));
|
|
}
|
|
|
|
@Override
|
|
public void onGenresAdded(@NonNull Collection<Genre> genres) {
|
|
Executors.uiThreadExecutor().execute(() -> addGenres(genres));
|
|
}
|
|
|
|
@Override
|
|
public void onPlaylistsAdded(@NonNull Collection<Playlist> playlists) {
|
|
Executors.uiThreadExecutor().execute(() -> addPlaylists(playlists));
|
|
}
|
|
}, this);
|
|
|
|
mVideoStore = new VideoStore(contentResolver, new VideoStore.ChangeListener() {
|
|
@Override
|
|
public void onMoviesAdded(@NonNull Collection<Movie> movies) {
|
|
Executors.uiThreadExecutor().execute(() -> addMovies(movies));
|
|
}
|
|
|
|
@Override
|
|
public void onSeriesAdded(@NonNull Collection<Series> series) {
|
|
Executors.uiThreadExecutor().execute(() -> addSeries(series));
|
|
}
|
|
|
|
@Override
|
|
public void onEpisodesAdded(@NonNull Collection<Episode> episodes) {
|
|
Executors.uiThreadExecutor().execute(() -> addEpisodes(episodes));
|
|
}
|
|
|
|
@Override
|
|
public void onOthersAdded(@NonNull Collection<Other> others) {
|
|
Executors.uiThreadExecutor().execute(() -> addOthers(others));
|
|
}
|
|
}, this);
|
|
}
|
|
|
|
public void addAudioUpdateCallback(@NonNull UpdateCallback callback) {
|
|
addUpdateCallback(mAudioUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void removeAudioUpdateCallback(@NonNull UpdateCallback callback) {
|
|
removeUpdateCallback(mAudioUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void addArtistUpdateCallback(@NonNull UpdateCallback callback) {
|
|
addUpdateCallback(mArtistUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void removeArtistUpdateCallback(@NonNull UpdateCallback callback) {
|
|
removeUpdateCallback(mArtistUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void addAlbumUpdateCallback(@NonNull UpdateCallback callback) {
|
|
addUpdateCallback(mAlbumUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void removeAlbumUpdateCallback(@NonNull UpdateCallback callback) {
|
|
removeUpdateCallback(mAlbumUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void addGenreUpdateCallback(@NonNull UpdateCallback callback) {
|
|
addUpdateCallback(mGenreUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void removeGenreUpdateCallback(@NonNull UpdateCallback callback) {
|
|
removeUpdateCallback(mGenreUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void addPlaylistUpdateCallback(@NonNull UpdateCallback callback) {
|
|
addUpdateCallback(mPlaylistUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void removePlaylistUpdateCallback(@NonNull UpdateCallback callback) {
|
|
removeUpdateCallback(mPlaylistUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void addMovieUpdateCallback(@NonNull UpdateCallback callback) {
|
|
addUpdateCallback(mMovieUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void removeMovieUpdateCallback(@NonNull UpdateCallback callback) {
|
|
removeUpdateCallback(mMovieUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void addSeriesUpdateCallback(@NonNull UpdateCallback callback) {
|
|
addUpdateCallback(mSeriesUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void removeSeriesUpdateCallback(@NonNull UpdateCallback callback) {
|
|
removeUpdateCallback(mSeriesUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void addEpisodeUpdateCallback(@NonNull UpdateCallback callback) {
|
|
addUpdateCallback(mEpisodeUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void removeEpisodeUpdateCallback(@NonNull UpdateCallback callback) {
|
|
removeUpdateCallback(mEpisodeUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void addOtherUpdateCallback(@NonNull UpdateCallback callback) {
|
|
addUpdateCallback(mOtherUpdateCallbacks, callback);
|
|
}
|
|
|
|
public void removeOtherUpdateCallback(@NonNull UpdateCallback callback) {
|
|
removeUpdateCallback(mOtherUpdateCallbacks, callback);
|
|
}
|
|
|
|
@RequiresPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
public void load() {
|
|
Clog.i(TAG, "load()");
|
|
if (mLoaded.getAndSet(true)) {
|
|
return;
|
|
}
|
|
|
|
mExecutor.execute(mAudioStore::load);
|
|
mExecutor.execute(mVideoStore::load);
|
|
}
|
|
|
|
public @NonNull List<Audio> getAudios() {
|
|
return Collections.unmodifiableList(mAudios);
|
|
}
|
|
public @NonNull List<Artist> getArtists() {
|
|
return Collections.unmodifiableList(mArtists);
|
|
}
|
|
public @NonNull List<Album> getAlbums() {
|
|
return Collections.unmodifiableList(mAlbums);
|
|
}
|
|
public @NonNull List<Genre> getGenres() {
|
|
return Collections.unmodifiableList(mGenres);
|
|
}
|
|
public @NonNull List<Playlist> getPlaylists() {
|
|
return Collections.unmodifiableList(mPlaylists);
|
|
}
|
|
|
|
public @NonNull List<Movie> getMovies() {
|
|
return Collections.unmodifiableList(mMovies);
|
|
}
|
|
public @NonNull List<Series> getSeries() {
|
|
return Collections.unmodifiableList(mSeries);
|
|
}
|
|
public @NonNull List<Episode> getEpisodes() {
|
|
return Collections.unmodifiableList(mEpisodes);
|
|
}
|
|
public @NonNull List<Other> getOthers() {
|
|
return Collections.unmodifiableList(mOthers);
|
|
}
|
|
|
|
public void loadData(@NonNull Audio audio) {
|
|
// TODO(b/123707632) Ensure no concurrent runs for the same item !!
|
|
if (audio.isLoaded()) return;
|
|
|
|
mExecutor.execute(() -> {
|
|
boolean updated = mAudioStore.loadData(audio);
|
|
|
|
audio.setLoaded();
|
|
if (updated) {
|
|
Executors.uiThreadExecutor().execute(() -> updateAudio(audio));
|
|
}
|
|
});
|
|
}
|
|
|
|
public void loadData(@NonNull Artist artist) {
|
|
// TODO(b/123707632) Ensure no concurrent runs for the same item !!
|
|
if (artist.isLoaded()) return;
|
|
|
|
mExecutor.execute(() -> {
|
|
try {
|
|
boolean updated = mDataProvider.populateArtist(artist);
|
|
|
|
updated |= mAudioStore.loadData(artist);
|
|
|
|
artist.setLoaded();
|
|
if (updated) {
|
|
Executors.uiThreadExecutor().execute(() -> updateArtist(artist));
|
|
}
|
|
} catch (IOException e) {
|
|
Clog.e(TAG, "Search for " + artist + " failed", e);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void loadData(@NonNull Album album) {
|
|
// TODO(b/123707632) Ensure no concurrent runs for the same item !!
|
|
if (album.isLoaded()) return;
|
|
|
|
mExecutor.execute(() -> {
|
|
try {
|
|
boolean updated = mDataProvider.populateAlbum(album);
|
|
|
|
updated |= mAudioStore.loadData(album);
|
|
|
|
album.setLoaded();
|
|
if (updated) {
|
|
Executors.uiThreadExecutor().execute(() -> updateAlbum(album));
|
|
}
|
|
} catch (IOException e) {
|
|
Clog.e(TAG, "Search for " + album + " failed", e);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void loadData(@NonNull Genre genre) {
|
|
// TODO(b/123707632) Ensure no concurrent runs for the same item !!
|
|
if (genre.isLoaded()) return;
|
|
|
|
mExecutor.execute(() -> {
|
|
boolean updated = mAudioStore.loadData(genre);
|
|
|
|
genre.setLoaded();
|
|
if (updated) {
|
|
Executors.uiThreadExecutor().execute(() -> updateGenre(genre));
|
|
}
|
|
});
|
|
}
|
|
|
|
public void loadData(@NonNull Playlist playlist) {
|
|
// TODO(b/123707632) Ensure no concurrent runs for the same item !!
|
|
if (playlist.isLoaded()) return;
|
|
|
|
mExecutor.execute(() -> {
|
|
boolean updated = mAudioStore.loadData(playlist);
|
|
|
|
playlist.setLoaded();
|
|
if (updated) {
|
|
Executors.uiThreadExecutor().execute(() -> updatePlaylist(playlist));
|
|
}
|
|
});
|
|
}
|
|
|
|
// TODO(b/123707018) Merge with loadData(episode)/loadData(other)
|
|
public void loadData(@NonNull Movie movie) {
|
|
// TODO(b/123707632) Ensure no concurrent runs for the same item !!
|
|
if (movie.isLoaded()) return;
|
|
|
|
mExecutor.execute(() -> {
|
|
try {
|
|
boolean updated = mDataProvider.populateMovie(movie);
|
|
|
|
updated |= mVideoStore.loadData(movie);
|
|
|
|
movie.setLoaded();
|
|
if (updated) {
|
|
Executors.uiThreadExecutor().execute(() -> updateMovie(movie));
|
|
}
|
|
} catch (IOException e) {
|
|
Clog.e(TAG, "Search for " + movie + " failed", e);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void loadData(@NonNull Series series) {
|
|
// TODO(b/123707632) Ensure no concurrent runs for the same item !!
|
|
if (series.isLoaded()) return;
|
|
|
|
mExecutor.execute(() -> {
|
|
try {
|
|
boolean updated = mDataProvider.populateSeries(series);
|
|
|
|
updated |= mVideoStore.loadData(series);
|
|
|
|
series.setLoaded();
|
|
if (updated) {
|
|
Executors.uiThreadExecutor().execute(() -> updateSeries(series));
|
|
}
|
|
} catch (IOException e) {
|
|
Clog.e(TAG, "Search for " + series + " failed", e);
|
|
}
|
|
});
|
|
}
|
|
|
|
// TODO(b/123707018) Merge with loadData(movie)/loadData(other)
|
|
public void loadData(@NonNull Episode episode) {
|
|
// TODO(b/123707632) Ensure no concurrent runs for the same item !!
|
|
if (episode.isLoaded()) return;
|
|
|
|
mExecutor.execute(() -> {
|
|
try {
|
|
boolean updated = mDataProvider.populateEpisode(episode);
|
|
|
|
updated |= mVideoStore.loadData(episode);
|
|
|
|
episode.setLoaded();
|
|
if (updated) {
|
|
Executors.uiThreadExecutor().execute(() -> updateEpisode(episode));
|
|
}
|
|
} catch (IOException e) {
|
|
Clog.e(TAG, "Search for " + episode + " failed", e);
|
|
}
|
|
});
|
|
}
|
|
|
|
// TODO(b/123707018) Merge with loadData(movie)/loadData(episode)
|
|
public void loadData(@NonNull Other other) {
|
|
// TODO(b/123707632) Ensure no concurrent runs for the same item !!
|
|
if (other.isLoaded()) return;
|
|
|
|
mExecutor.execute(() -> {
|
|
boolean updated = mVideoStore.loadData(other);
|
|
|
|
other.setLoaded();
|
|
if (updated) {
|
|
Executors.uiThreadExecutor().execute(() -> updateOther(other));
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Audio getAudioById(long id) {
|
|
for (Audio audio : mAudios) {
|
|
if (audio.getId() == id) {
|
|
return audio;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Audio with id " + id + " was not found");
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Artist getArtistById(long id) {
|
|
for (Artist artist : mArtists) {
|
|
if (artist.getId() == id) {
|
|
return artist;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Artist with id " + id + " was not found");
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Album getAlbumById(long id) {
|
|
for (Album album : mAlbums) {
|
|
if (album.getId() == id) {
|
|
return album;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Album with id " + id + " was not found");
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Genre getGenreById(long id) {
|
|
for (Genre genre : mGenres) {
|
|
if (genre.getId() == id) {
|
|
return genre;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Genre with id " + id + " was not found");
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Playlist getPlaylistById(long id) {
|
|
for (Playlist playlist : mPlaylists) {
|
|
if (playlist.getId() == id) {
|
|
return playlist;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Playlist with id " + id + " was not found");
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Movie getMovieById(long id) {
|
|
for (Movie movie : mMovies) {
|
|
if (movie.getId() == id) {
|
|
return movie;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Movie with id " + id + " was not found");
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Series getSeriesById(@NonNull String title) {
|
|
for (Series series : mSeries) {
|
|
if (!series.hasYear() && series.getTitle().equals(title)) {
|
|
return series;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Series '" + title + "' was not found");
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Series getSeriesById(@NonNull String title, int year) {
|
|
for (Series series : mSeries) {
|
|
if (series.hasYear() && series.getTitle().equals(title) && series.getYear() == year) {
|
|
return series;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Series '" + title + "' (" + year + ") was not found");
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Episode getEpisodeById(long id) {
|
|
for (Episode episode : mEpisodes) {
|
|
if (episode.getId() == id) {
|
|
return episode;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Episode with id " + id + " was not found");
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Other getOtherById(long id) {
|
|
for (Other other : mOthers) {
|
|
if (other.getId() == id) {
|
|
return other;
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Other with id " + id + " was not found");
|
|
}
|
|
|
|
private void addUpdateCallback(@NonNull Set<UpdateCallback> callbacks,
|
|
@NonNull UpdateCallback callback) {
|
|
if (!callbacks.add(callback)) {
|
|
throw new IllegalArgumentException("Callback " + callback + " already added in " +
|
|
callbacks);
|
|
}
|
|
}
|
|
|
|
private void removeUpdateCallback(@NonNull Set<UpdateCallback> callbacks,
|
|
@NonNull UpdateCallback callback) {
|
|
if (!callbacks.remove(callback)) {
|
|
throw new IllegalArgumentException("Callback " + callback + " not found in " +
|
|
callbacks);
|
|
}
|
|
}
|
|
|
|
private void addAudios(@NonNull Collection<Audio> audios) {
|
|
int audiosIndex = mAudios.size();
|
|
int audiosCount = 0;
|
|
|
|
mAudios.addAll(audios);
|
|
audiosCount += audios.size();
|
|
|
|
if (audiosCount > 0) {
|
|
for (UpdateCallback callback : mAudioUpdateCallbacks) {
|
|
callback.onItemsInserted(audiosIndex, audiosCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addArtists(@NonNull Collection<Artist> artists) {
|
|
int artistsIndex = mArtists.size();
|
|
int artistsCount = 0;
|
|
|
|
mArtists.addAll(artists);
|
|
artistsCount += artists.size();
|
|
|
|
if (artistsCount > 0) {
|
|
for (UpdateCallback callback : mArtistUpdateCallbacks) {
|
|
callback.onItemsInserted(artistsIndex, artistsCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addAlbums(@NonNull Collection<Album> albums) {
|
|
int albumsIndex = mAlbums.size();
|
|
int albumsCount = 0;
|
|
|
|
mAlbums.addAll(albums);
|
|
albumsCount += albums.size();
|
|
|
|
if (albumsCount > 0) {
|
|
for (UpdateCallback callback : mAlbumUpdateCallbacks) {
|
|
callback.onItemsInserted(albumsIndex, albumsCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addGenres(@NonNull Collection<Genre> genres) {
|
|
int genresIndex = mGenres.size();
|
|
int genresCount = 0;
|
|
|
|
mGenres.addAll(genres);
|
|
genresCount += genres.size();
|
|
|
|
if (genresCount > 0) {
|
|
for (UpdateCallback callback : mGenreUpdateCallbacks) {
|
|
callback.onItemsInserted(genresIndex, genresCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addPlaylists(@NonNull Collection<Playlist> playlists) {
|
|
int playlistsIndex = mPlaylists.size();
|
|
int playlistsCount = 0;
|
|
|
|
mPlaylists.addAll(playlists);
|
|
playlistsCount += playlists.size();
|
|
|
|
if (playlistsCount > 0) {
|
|
for (UpdateCallback callback : mPlaylistUpdateCallbacks) {
|
|
callback.onItemsInserted(playlistsIndex, playlistsCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addMovies(@NonNull Collection<Movie> movies) {
|
|
int moviesIndex = mMovies.size();
|
|
int moviesCount = 0;
|
|
|
|
mMovies.addAll(movies);
|
|
moviesCount += movies.size();
|
|
|
|
if (moviesCount > 0) {
|
|
for (UpdateCallback callback : mMovieUpdateCallbacks) {
|
|
callback.onItemsInserted(moviesIndex, moviesCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addSeries(@NonNull Collection<Series> series) {
|
|
int seriesIndex = mSeries.size();
|
|
int seriesCount = 0;
|
|
|
|
mSeries.addAll(series);
|
|
seriesCount += series.size();
|
|
|
|
if (seriesCount > 0) {
|
|
for (UpdateCallback callback : mSeriesUpdateCallbacks) {
|
|
callback.onItemsInserted(seriesIndex, seriesCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addEpisodes(@NonNull Collection<Episode> episodes) {
|
|
int episodesIndex = mEpisodes.size();
|
|
int episodesCount = 0;
|
|
|
|
mEpisodes.addAll(episodes);
|
|
episodesCount += episodes.size();
|
|
|
|
if (episodesCount > 0) {
|
|
for (UpdateCallback callback : mEpisodeUpdateCallbacks) {
|
|
callback.onItemsInserted(episodesIndex, episodesCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addOthers(@NonNull Collection<Other> others) {
|
|
int othersIndex = mOthers.size();
|
|
int othersCount = 0;
|
|
|
|
mOthers.addAll(others);
|
|
othersCount += others.size();
|
|
|
|
if (othersCount > 0) {
|
|
for (UpdateCallback callback : mOtherUpdateCallbacks) {
|
|
callback.onItemsInserted(othersIndex, othersCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateAudio(@NonNull Audio audio) {
|
|
int index = mAudios.indexOf(audio);
|
|
if (index != -1) {
|
|
for (UpdateCallback callback : mAudioUpdateCallbacks) {
|
|
callback.onItemsUpdated(index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateArtist(@NonNull Artist artist) {
|
|
int index = mArtists.indexOf(artist);
|
|
if (index != -1) {
|
|
for (UpdateCallback callback : mArtistUpdateCallbacks) {
|
|
callback.onItemsUpdated(index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateAlbum(@NonNull Album album) {
|
|
int index = mAlbums.indexOf(album);
|
|
if (index != -1) {
|
|
for (UpdateCallback callback : mAlbumUpdateCallbacks) {
|
|
callback.onItemsUpdated(index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateGenre(@NonNull Genre genre) {
|
|
int index = mGenres.indexOf(genre);
|
|
if (index != -1) {
|
|
for (UpdateCallback callback : mGenreUpdateCallbacks) {
|
|
callback.onItemsUpdated(index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updatePlaylist(@NonNull Playlist playlist) {
|
|
int index = mPlaylists.indexOf(playlist);
|
|
if (index != -1) {
|
|
for (UpdateCallback callback : mPlaylistUpdateCallbacks) {
|
|
callback.onItemsUpdated(index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateMovie(@NonNull Movie movie) {
|
|
int index = mMovies.indexOf(movie);
|
|
if (index != -1) {
|
|
for (UpdateCallback callback : mMovieUpdateCallbacks) {
|
|
callback.onItemsUpdated(index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateSeries(@NonNull Series series) {
|
|
int index = mSeries.indexOf(series);
|
|
if (index != -1) {
|
|
for (UpdateCallback callback : mSeriesUpdateCallbacks) {
|
|
callback.onItemsUpdated(index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateEpisode(@NonNull Episode episode) {
|
|
int index = mEpisodes.indexOf(episode);
|
|
if (index != -1) {
|
|
for (UpdateCallback callback : mEpisodeUpdateCallbacks) {
|
|
callback.onItemsUpdated(index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateOther(@NonNull Other other) {
|
|
int index = mOthers.indexOf(other);
|
|
if (index != -1) {
|
|
for (UpdateCallback callback : mOtherUpdateCallbacks) {
|
|
callback.onItemsUpdated(index, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|