package org.moire.ultrasonic.service; import android.content.Context; import android.os.AsyncTask; import timber.log.Timber; import org.moire.ultrasonic.util.Constants; import org.moire.ultrasonic.util.FileUtil; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * This class is responsible for the serialization / deserialization * of the DownloadQueue (playlist) to the filesystem. * It also serializes the player state e.g. current playing number and play position. */ public class DownloadQueueSerializer { public final Lock lock = new ReentrantLock(); public final AtomicBoolean setup = new AtomicBoolean(false); private Context context; public DownloadQueueSerializer(Context context) { this.context = context; } public void serializeDownloadQueue(Iterable songs, int currentPlayingIndex, int currentPlayingPosition) { if (!setup.get()) { return; } new SerializeTask().execute(songs, currentPlayingIndex, currentPlayingPosition); } public void serializeDownloadQueueNow(Iterable songs, int currentPlayingIndex, int currentPlayingPosition) { State state = new State(); for (DownloadFile downloadFile : songs) { state.songs.add(downloadFile.getSong()); } state.currentPlayingIndex = currentPlayingIndex; state.currentPlayingPosition = currentPlayingPosition; Timber.i("Serialized currentPlayingIndex: %d, currentPlayingPosition: %d", state.currentPlayingIndex, state.currentPlayingPosition); FileUtil.serialize(context, state, Constants.FILENAME_DOWNLOADS_SER); } public void deserializeDownloadQueue(Consumer afterDeserialized) { new DeserializeTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, afterDeserialized); } public void deserializeDownloadQueueNow(Consumer afterDeserialized) { State state = FileUtil.deserialize(context, Constants.FILENAME_DOWNLOADS_SER); if (state == null) return; Timber.i("Deserialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); afterDeserialized.accept(state); } private class SerializeTask extends AsyncTask { @Override protected Void doInBackground(Object... params) { if (lock.tryLock()) { try { Thread.currentThread().setName("SerializeTask"); serializeDownloadQueueNow((Iterable)params[0], (int)params[1], (int)params[2]); } finally { lock.unlock(); } } return null; } } private class DeserializeTask extends AsyncTask { @Override protected Void doInBackground(Object... params) { try { Thread.currentThread().setName("DeserializeTask"); lock.lock(); deserializeDownloadQueueNow((Consumer)params[0]); setup.set(true); } finally { lock.unlock(); } return null; } } }