aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorScott Jackson <daneren2005@gmail.com>2015-07-13 19:36:58 -0700
committerScott Jackson <daneren2005@gmail.com>2015-07-13 19:37:09 -0700
commita12581051e8bce57c085a50082c47edbe5848036 (patch)
tree14ddeb684cbea13550ae3c46d0b2c0215d172946 /app
parentad11c8479efb9ebce977edee15cdeb2838deba63 (diff)
downloaddsub-a12581051e8bce57c085a50082c47edbe5848036.tar.gz
dsub-a12581051e8bce57c085a50082c47edbe5848036.tar.bz2
dsub-a12581051e8bce57c085a50082c47edbe5848036.zip
#527 Change from polling to using DownloadService events
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java22
-rw-r--r--app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java152
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java539
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/DownloadService.java92
4 files changed, 369 insertions, 436 deletions
diff --git a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
index 33d978bf..1492c778 100644
--- a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
+++ b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
@@ -29,6 +29,7 @@ import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
+import android.os.Handler;
import android.support.design.widget.NavigationView;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
@@ -82,6 +83,7 @@ public class SubsonicActivity extends AppCompatActivity implements OnItemSelecte
private static final int MENU_GROUP_SERVER = 10;
private static final int MENU_ITEM_SERVER_BASE = 100;
+ private final List<Runnable> afterServiceAvailable = new ArrayList<>();
private boolean drawerIdle = true;
private boolean destroyed = false;
private boolean finished = false;
@@ -91,6 +93,7 @@ public class SubsonicActivity extends AppCompatActivity implements OnItemSelecte
protected View secondaryContainer;
protected boolean tv = false;
protected boolean touchscreen = true;
+ protected Handler handler = new Handler();
Spinner actionBarSpinner;
ArrayAdapter<CharSequence> spinnerAdapter;
ViewGroup rootView;
@@ -871,13 +874,28 @@ public class SubsonicActivity extends AppCompatActivity implements OnItemSelecte
for (int i = 0; i < 5; i++) {
DownloadService downloadService = DownloadService.getInstance();
if (downloadService != null) {
- return downloadService;
+ break;
}
Log.w(TAG, "DownloadService not running. Attempting to start it.");
startService(new Intent(this, DownloadService.class));
Util.sleepQuietly(50L);
}
- return DownloadService.getInstance();
+
+ final DownloadService downloadService = DownloadService.getInstance();
+ if(downloadService != null && afterServiceAvailable.size() > 0) {
+ for(Runnable runnable: afterServiceAvailable) {
+ handler.post(runnable);
+ }
+ afterServiceAvailable.clear();
+ }
+ return downloadService;
+ }
+ public void runWhenServiceAvailable(Runnable runnable) {
+ if(getDownloadService() != null) {
+ runnable.run();
+ } else {
+ afterServiceAvailable.add(runnable);
+ }
}
public static String getThemeName() {
diff --git a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
index f0685a5f..e5144f6f 100644
--- a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
+++ b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
@@ -45,6 +45,7 @@ import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import java.io.File;
import java.util.Date;
+import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -82,13 +83,12 @@ import github.daneren2005.dsub.view.ChangeLog;
/**
* Created by Scott on 10/14/13.
*/
-public class SubsonicFragmentActivity extends SubsonicActivity {
+public class SubsonicFragmentActivity extends SubsonicActivity implements DownloadService.OnSongChangedListener {
private static String TAG = SubsonicFragmentActivity.class.getSimpleName();
private static boolean infoDialogDisplayed;
private static boolean sessionInitialized = false;
private static long ALLOWED_SKEW = 30000L;
- private Handler handler = new Handler();
private SlidingUpPanelLayout slideUpPanel;
private SlidingUpPanelLayout.PanelSlideListener panelSlideListener;
private NowPlayingFragment nowPlayingFragment;
@@ -96,7 +96,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
private Toolbar mainToolbar;
private Toolbar nowPlayingToolbar;
- private ScheduledExecutorService executorService;
private View bottomBar;
private ImageView coverArtView;
private TextView trackView;
@@ -292,11 +291,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
getDownloadService().previous();
return null;
}
-
- @Override
- protected void done(Void result) {
- update();
- }
}.execute();
}
});
@@ -317,11 +311,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
return null;
}
-
- @Override
- protected void done(Void result) {
- update();
- }
}.execute();
}
});
@@ -340,11 +329,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
getDownloadService().next();
return null;
}
-
- @Override
- protected void done(Void result) {
- update();
- }
}.execute();
}
});
@@ -406,18 +390,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
public void onResume() {
super.onResume();
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- handler.post(new Runnable() {
- @Override
- public void run() {
- update();
- }
- });
- }
- };
-
if(getIntent().hasExtra(Constants.INTENT_EXTRA_VIEW_ALBUM)) {
SubsonicFragment fragment = new SelectDirectoryFragment();
Bundle args = new Bundle();
@@ -437,15 +409,21 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
}
createAccount();
-
- executorService = Executors.newSingleThreadScheduledExecutor();
- executorService.scheduleWithFixedDelay(runnable, 0L, 1000L, TimeUnit.MILLISECONDS);
+ runWhenServiceAvailable(new Runnable() {
+ @Override
+ public void run() {
+ getDownloadService().addOnSongChangedListener(SubsonicFragmentActivity.this, true);
+ }
+ });
}
@Override
public void onPause() {
super.onPause();
- executorService.shutdown();
+ DownloadService downloadService = getDownloadService();
+ if(downloadService != null) {
+ downloadService.removeOnSongChangeListener(this);
+ }
}
@Override
@@ -638,54 +616,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
}
}
- private void update() {
- DownloadService downloadService = getDownloadService();
- if (downloadService == null) {
- return;
- }
-
- DownloadFile current = downloadService.getCurrentPlaying();
- PlayerState state = downloadService.getPlayerState();
- if(current == currentPlaying && state == currentState) {
- if(current == null && slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
- slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.HIDDEN);
- }
- return;
- } else {
- currentPlaying = current;
- currentState = state;
- }
-
- MusicDirectory.Entry song = null;
- if (current != null) {
- song = current.getSong();
- trackView.setText(song.getTitle());
- artistView.setText(song.getArtist());
-
- if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.HIDDEN) {
- slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
- }
- } else if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
- slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.HIDDEN);
- }
-
- if (coverArtView != null) {
- int height = coverArtView.getHeight();
- if (height <= 0) {
- int[] attrs = new int[]{R.attr.actionBarSize};
- TypedArray typedArray = this.obtainStyledAttributes(attrs);
- height = typedArray.getDimensionPixelSize(0, 0);
- typedArray.recycle();
- }
- getImageLoader().loadImage(coverArtView, song, false, height, false);
- }
-
- int[] attrs = new int[]{(state == PlayerState.STARTED) ? R.attr.actionbar_pause : R.attr.actionbar_start};
- TypedArray typedArray = this.obtainStyledAttributes(attrs);
- startButton.setImageResource(typedArray.getResourceId(0, 0));
- typedArray.recycle();
- }
-
public void checkUpdates() {
try {
String version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
@@ -892,4 +822,62 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
public Toolbar getActiveToolbar() {
return slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED ? nowPlayingToolbar : mainToolbar;
}
+
+ @Override
+ public void onSongChanged(DownloadFile currentPlaying, int currentPlayingIndex) {
+ DownloadService downloadService = getDownloadService();
+ PlayerState state = downloadService.getPlayerState();
+ if(currentPlaying == this.currentPlaying && state == currentState) {
+ if(currentPlaying == null && slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
+ slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.HIDDEN);
+ }
+ return;
+ } else {
+ this.currentPlaying = currentPlaying;
+ }
+
+ MusicDirectory.Entry song = null;
+ if (currentPlaying != null) {
+ song = currentPlaying.getSong();
+ trackView.setText(song.getTitle());
+ artistView.setText(song.getArtist());
+
+ if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.HIDDEN) {
+ slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
+ }
+ } else if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
+ slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.HIDDEN);
+ }
+
+ if (coverArtView != null) {
+ int height = coverArtView.getHeight();
+ if (height <= 0) {
+ int[] attrs = new int[]{R.attr.actionBarSize};
+ TypedArray typedArray = this.obtainStyledAttributes(attrs);
+ height = typedArray.getDimensionPixelSize(0, 0);
+ typedArray.recycle();
+ }
+ getImageLoader().loadImage(coverArtView, song, false, height, false);
+ }
+ }
+
+ @Override
+ public void onSongsChanged(List<DownloadFile> songs, DownloadFile currentPlaying, int currentPlayingIndex) {
+ if(this.currentPlaying != currentPlaying) {
+ onSongChanged(currentPlaying, currentPlayingIndex);
+ }
+ }
+
+ @Override
+ public void onSongProgress(DownloadFile currentPlaying, int millisPlayed, Integer duration, boolean isSeekable) {
+
+ }
+
+ @Override
+ public void onStateUpdate(DownloadFile downloadFile, PlayerState playerState) {
+ int[] attrs = new int[]{(playerState == PlayerState.STARTED) ? R.attr.actionbar_pause : R.attr.actionbar_start};
+ TypedArray typedArray = this.obtainStyledAttributes(attrs);
+ startButton.setImageResource(typedArray.getResourceId(0, 0));
+ typedArray.recycle();
+ }
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java
index 1b652f57..a75470e9 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java
@@ -66,6 +66,7 @@ import github.daneren2005.dsub.domain.RepeatMode;
import github.daneren2005.dsub.domain.ServerInfo;
import github.daneren2005.dsub.service.DownloadFile;
import github.daneren2005.dsub.service.DownloadService;
+import github.daneren2005.dsub.service.DownloadService.OnSongChangedListener;
import github.daneren2005.dsub.service.MusicService;
import github.daneren2005.dsub.service.MusicServiceFactory;
import github.daneren2005.dsub.service.OfflineException;
@@ -86,11 +87,10 @@ import java.util.ArrayList;
import java.util.concurrent.ScheduledFuture;
import github.daneren2005.dsub.activity.SubsonicActivity;
-public class NowPlayingFragment extends SubsonicFragment implements OnGestureListener, SectionAdapter.OnItemClickedListener<DownloadFile> {
+public class NowPlayingFragment extends SubsonicFragment implements OnGestureListener, SectionAdapter.OnItemClickedListener<DownloadFile>, OnSongChangedListener {
private static final String TAG = NowPlayingFragment.class.getSimpleName();
private static final int PERCENTAGE_OF_SCREEN_FOR_SWIPE = 10;
private static final int INCREMENT_TIME = 5000;
- private static final int SERVICE_BACKOFF = 200;
private static final int ACTION_PREVIOUS = 1;
private static final int ACTION_NEXT = 2;
@@ -126,13 +126,11 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
private ScheduledFuture<?> hideControlsFuture;
private List<DownloadFile> songList;
private DownloadFileAdapter songListAdapter;
- private SilentBackgroundTask<Void> onProgressChangedTask;
- private SilentBackgroundTask<Void> onCurrentChangedTask;
- private SilentBackgroundTask<Void> onDownloadListChangedTask;
private boolean seekInProgress = false;
private boolean startFlipped = false;
private boolean scrollWhenLoaded = false;
private int lastY = 0;
+ private int currentPlayingSize = 0;
/**
* Called when the activity is first created.
@@ -280,12 +278,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
getDownloadService().previous();
return null;
}
-
- @Override
- protected void done(Void result) {
- onCurrentChanged();
- onProgressChanged();
- }
}.execute();
setControlsVisible(true);
}
@@ -306,14 +298,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
getDownloadService().next();
return true;
}
-
- @Override
- protected void done(Boolean result) {
- if (result) {
- onCurrentChanged();
- onProgressChanged();
- }
- }
}.execute();
setControlsVisible(true);
}
@@ -333,12 +317,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
getDownloadService().pause();
return null;
}
-
- @Override
- protected void done(Void result) {
- onCurrentChanged();
- onProgressChanged();
- }
}.execute();
}
});
@@ -352,12 +330,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
getDownloadService().reset();
return null;
}
-
- @Override
- protected void done(Void result) {
- onCurrentChanged();
- onProgressChanged();
- }
}.execute();
}
});
@@ -372,12 +344,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
start();
return null;
}
-
- @Override
- protected void done(Void result) {
- onCurrentChanged();
- onProgressChanged();
- }
}.execute();
}
});
@@ -387,7 +353,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
public void onClick(View view) {
RepeatMode repeatMode = getDownloadService().getRepeatMode().next();
getDownloadService().setRepeatMode(repeatMode);
- onDownloadListChanged();
switch (repeatMode) {
case OFF:
Util.toast(context, R.string.download_repeat_off);
@@ -523,7 +488,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
@Override
protected void done(Void result) {
seekInProgress = false;
- NowPlayingFragment.this.onProgressChanged();
}
}.execute();
}
@@ -811,24 +775,10 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
private void onResumeHandlers() {
final Handler handler = new Handler();
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- handler.post(new Runnable() {
- @Override
- public void run() {
- update();
- }
- });
- }
- };
-
executorService = Executors.newSingleThreadScheduledExecutor();
- executorService.scheduleWithFixedDelay(runnable, 0L, 1000L, TimeUnit.MILLISECONDS);
-
setControlsVisible(true);
- DownloadService downloadService = getDownloadService();
+ final DownloadService downloadService = getDownloadService();
if (downloadService == null || downloadService.getCurrentPlaying() == null || startFlipped) {
playlistFlipper.setDisplayedChild(1);
}
@@ -843,24 +793,17 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if(currentPlaying == null && downloadService != null && currentPlaying == downloadService.getCurrentPlaying()) {
getImageLoader().loadImage(albumArtImageView, (Entry) null, true, false);
}
- if(downloadService != null) {
- downloadService.startRemoteScan();
- } else {
- // Make sure to call remote scan once the service is ready
- final Runnable waitForService = new Runnable() {
- @Override
- public void run() {
- DownloadService service = getDownloadService();
- if(service != null) {
- service.startRemoteScan();
- } else {
- handler.postDelayed(this, SERVICE_BACKOFF);
- }
- }
- };
- handler.postDelayed(waitForService, SERVICE_BACKOFF);
- }
+ context.runWhenServiceAvailable(new Runnable() {
+ @Override
+ public void run() {
+ if(primaryFragment) {
+ DownloadService downloadService = getDownloadService();
+ downloadService.startRemoteScan();
+ downloadService.addOnSongChangedListener(NowPlayingFragment.this, true);
+ }
+ }
+ });
}
@Override
@@ -870,11 +813,11 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
private void onPauseHandlers() {
if(executorService != null) {
- executorService.shutdown();
- if (getDownloadService() != null) {
- getDownloadService().stopRemoteScan();
+ DownloadService downloadService = getDownloadService();
+ if (downloadService != null) {
+ downloadService.stopRemoteScan();
+ downloadService.removeOnSongChangeListener(this);
}
- executorService = null;
playlistFlipper.setDisplayedChild(0);
}
}
@@ -983,24 +926,10 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
private void update() {
- if (getDownloadService() == null) {
- return;
- }
-
- if (currentRevision != getDownloadService().getDownloadListUpdateRevision()) {
- onDownloadListChanged();
- }
-
- if (currentPlaying != getDownloadService().getCurrentPlaying()) {
- onCurrentChanged();
- }
-
if(startFlipped) {
startFlipped = false;
scrollToCurrent();
}
-
- onProgressChanged();
}
protected void startTimer() {
@@ -1098,258 +1027,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
}
}
- private void onDownloadListChanged() {
- onDownloadListChanged(false);
- }
- private void onDownloadListChanged(final boolean refresh) {
- final DownloadService downloadService = getDownloadService();
- if (downloadService == null || onDownloadListChangedTask != null) {
- return;
- }
-
- onDownloadListChangedTask = new SilentBackgroundTask<Void>(context) {
- int currentPlayingIndex;
- int size;
-
- @Override
- protected Void doInBackground() throws Throwable {
- currentPlayingIndex = downloadService.getCurrentPlayingIndex() + 1;
- size = downloadService.size();
-
- return null;
- }
-
- @Override
- protected void done(Void result) {
- List<DownloadFile> list;
- list = downloadService.getSongs();
-
- if(downloadService.isShufflePlayEnabled()) {
- emptyTextView.setText(R.string.download_shuffle_loading);
- }
- else {
- emptyTextView.setText(R.string.download_empty);
- }
-
- if(songListAdapter == null || refresh) {
- songList = new ArrayList<>();
- songList.addAll(list);
- playlistView.setAdapter(songListAdapter = new DownloadFileAdapter(context, songList, NowPlayingFragment.this));
- } else {
- songList.clear();
- songList.addAll(list);
- songListAdapter.notifyDataSetChanged();
- }
-
- emptyTextView.setVisibility(list.isEmpty() ? View.VISIBLE : View.GONE);
- currentRevision = downloadService.getDownloadListUpdateRevision();
-
- switch (downloadService.getRepeatMode()) {
- case OFF:
- if("light".equals(SubsonicActivity.getThemeName()) | "light_fullscreen".equals(SubsonicActivity.getThemeName())) {
- repeatButton.setImageResource(R.drawable.media_repeat_off_light);
- } else {
- repeatButton.setImageResource(R.drawable.media_repeat_off);
- }
- break;
- case ALL:
- repeatButton.setImageResource(R.drawable.media_repeat_all);
- break;
- case SINGLE:
- repeatButton.setImageResource(R.drawable.media_repeat_single);
- break;
- default:
- break;
- }
-
- if(scrollWhenLoaded) {
- scrollToCurrent();
- scrollWhenLoaded = false;
- }
-
- setSubtitle(context.getResources().getString(R.string.download_playing_out_of, currentPlayingIndex, size));
- onDownloadListChangedTask = null;
- if(onCurrentChangedTask != null) {
- onCurrentChangedTask.execute();
- } else if(onProgressChangedTask != null) {
- onProgressChangedTask.execute();
- }
- }
- };
- onDownloadListChangedTask.execute();
- }
-
- private void onCurrentChanged() {
- final DownloadService downloadService = getDownloadService();
- if (downloadService == null || onCurrentChangedTask != null) {
- return;
- }
-
- onCurrentChangedTask = new SilentBackgroundTask<Void>(context) {
- int currentPlayingIndex;
- int currentPlayingSize;
-
- @Override
- protected Void doInBackground() throws Throwable {
- currentPlaying = downloadService.getCurrentPlaying();
- currentPlayingIndex = downloadService.getCurrentPlayingIndex() + 1;
- currentPlayingSize = downloadService.size();
- return null;
- }
-
- @Override
- protected void done(Void result) {
- if (currentPlaying != null) {
- Entry song = currentPlaying.getSong();
- songTitleTextView.setText(song.getTitle());
- getImageLoader().loadImage(albumArtImageView, song, true, true);
- starButton.setImageResource(song.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
- setSubtitle(context.getResources().getString(R.string.download_playing_out_of, currentPlayingIndex, currentPlayingSize));
-
- int badRating, goodRating, bookmark;
- if(song.getRating() == 1) {
- badRating = R.drawable.ic_action_rating_bad_selected;
- } else if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
- badRating = R.drawable.ic_action_rating_bad_dark;
- } else {
- badRating = Util.getAttribute(context, R.attr.rating_bad);
- }
- rateBadButton.setImageResource(badRating);
-
- if(song.getRating() == 5) {
- goodRating = R.drawable.ic_action_rating_good_selected;
- } else if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
- goodRating = R.drawable.ic_action_rating_good_dark;
- } else {
- goodRating = Util.getAttribute(context, R.attr.rating_good);
- }
- rateGoodButton.setImageResource(goodRating);
-
- if(song.getBookmark() != null) {
- bookmark = R.drawable.ic_menu_bookmark_selected;
- } else if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
- bookmark = R.drawable.ic_menu_bookmark_dark;
- } else {
- bookmark = Util.getAttribute(context, R.attr.bookmark);
- }
- bookmarkButton.setImageResource(bookmark);
- } else {
- songTitleTextView.setText(null);
- getImageLoader().loadImage(albumArtImageView, (Entry) null, true, false);
- starButton.setImageResource(android.R.drawable.btn_star_big_off);
- setSubtitle(null);
- }
- onCurrentChangedTask = null;
- if(onProgressChangedTask != null) {
- onProgressChangedTask.execute();
- }
- }
- };
-
- if(onDownloadListChangedTask == null) {
- onCurrentChangedTask.execute();
- }
- }
-
- private void onProgressChanged() {
- // Make sure to only be trying to run one of these at a time
- if (getDownloadService() == null || onProgressChangedTask != null) {
- return;
- }
-
- onProgressChangedTask = new SilentBackgroundTask<Void>(context) {
- DownloadService downloadService;
- int millisPlayed;
- Integer duration;
- PlayerState playerState;
- boolean isSeekable;
-
- @Override
- protected Void doInBackground() throws Throwable {
- downloadService = getDownloadService();
- millisPlayed = Math.max(0, downloadService.getPlayerPosition());
- duration = downloadService.getPlayerDuration();
- playerState = getDownloadService().getPlayerState();
- isSeekable = downloadService.isSeekable();
- return null;
- }
-
- @Override
- protected void done(Void result) {
- if (currentPlaying != null) {
- int millisTotal = duration == null ? 0 : duration;
-
- positionTextView.setText(Util.formatDuration(millisPlayed / 1000));
- if(millisTotal > 0) {
- durationTextView.setText(Util.formatDuration(millisTotal / 1000));
- } else {
- durationTextView.setText("-:--");
- }
- progressBar.setMax(millisTotal == 0 ? 100 : millisTotal); // Work-around for apparent bug.
- if(!seekInProgress) {
- progressBar.setProgress(millisPlayed);
- }
- progressBar.setEnabled(isSeekable);
- } else {
- positionTextView.setText("0:00");
- durationTextView.setText("-:--");
- progressBar.setProgress(0);
- progressBar.setEnabled(false);
- }
-
- switch (playerState) {
- case DOWNLOADING:
- if(currentPlaying != null) {
- if(Util.isWifiRequiredForDownload(context)) {
- statusTextView.setText(context.getResources().getString(R.string.download_playerstate_mobile_disabled));
- } else {
- long bytes = currentPlaying.getPartialFile().length();
- statusTextView.setText(context.getResources().getString(R.string.download_playerstate_downloading, Util.formatLocalizedBytes(bytes, context)));
- }
- }
- break;
- case PREPARING:
- statusTextView.setText(R.string.download_playerstate_buffering);
- break;
- default:
- if(currentPlaying != null) {
- String artist = "";
- if(currentPlaying.getSong().getArtist() != null) {
- artist = currentPlaying.getSong().getArtist() + " - ";
- }
- statusTextView.setText(artist + currentPlaying.getSong().getAlbum());
- } else {
- statusTextView.setText(null);
- }
- break;
- }
-
- switch (playerState) {
- case STARTED:
- pauseButton.setVisibility(View.VISIBLE);
- stopButton.setVisibility(View.INVISIBLE);
- startButton.setVisibility(View.INVISIBLE);
- break;
- case DOWNLOADING:
- case PREPARING:
- pauseButton.setVisibility(View.INVISIBLE);
- stopButton.setVisibility(View.VISIBLE);
- startButton.setVisibility(View.INVISIBLE);
- break;
- default:
- pauseButton.setVisibility(View.INVISIBLE);
- stopButton.setVisibility(View.INVISIBLE);
- startButton.setVisibility(View.VISIBLE);
- break;
- }
-
- onProgressChangedTask = null;
- }
- };
- if(onDownloadListChangedTask == null && onCurrentChangedTask == null) {
- onProgressChangedTask.execute();
- }
- }
private void changeProgress(final int ms) {
final DownloadService downloadService = getDownloadService();
@@ -1528,11 +1205,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
downloadService.seekTo(downloadService.getPlayerPosition() - DownloadService.REWIND);
break;
}
-
- onProgressChanged();
- if(performAction == ACTION_NEXT || performAction == ACTION_PREVIOUS) {
- onCurrentChanged();
- }
return null;
}
}.execute();
@@ -1568,11 +1240,180 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
@Override
protected Void doInBackground() throws Throwable {
getDownloadService().play(item);
-
- onCurrentChanged();
- onProgressChanged();
return null;
}
}.execute();
}
+
+ @Override
+ public void onSongChanged(DownloadFile currentPlaying, int currentPlayingIndex) {
+ this.currentPlaying = currentPlaying;
+ if (currentPlaying != null) {
+ Entry song = currentPlaying.getSong();
+ songTitleTextView.setText(song.getTitle());
+ getImageLoader().loadImage(albumArtImageView, song, true, true);
+ starButton.setImageResource(song.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
+ setSubtitle(context.getResources().getString(R.string.download_playing_out_of, currentPlayingIndex, currentPlayingSize));
+
+ int badRating, goodRating, bookmark;
+ if(song.getRating() == 1) {
+ badRating = R.drawable.ic_action_rating_bad_selected;
+ } else if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ badRating = R.drawable.ic_action_rating_bad_dark;
+ } else {
+ badRating = Util.getAttribute(context, R.attr.rating_bad);
+ }
+ rateBadButton.setImageResource(badRating);
+
+ if(song.getRating() == 5) {
+ goodRating = R.drawable.ic_action_rating_good_selected;
+ } else if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ goodRating = R.drawable.ic_action_rating_good_dark;
+ } else {
+ goodRating = Util.getAttribute(context, R.attr.rating_good);
+ }
+ rateGoodButton.setImageResource(goodRating);
+
+ if(song.getBookmark() != null) {
+ bookmark = R.drawable.ic_menu_bookmark_selected;
+ } else if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ bookmark = R.drawable.ic_menu_bookmark_dark;
+ } else {
+ bookmark = Util.getAttribute(context, R.attr.bookmark);
+ }
+ bookmarkButton.setImageResource(bookmark);
+ } else {
+ songTitleTextView.setText(null);
+ getImageLoader().loadImage(albumArtImageView, null, true, false);
+ starButton.setImageResource(android.R.drawable.btn_star_big_off);
+ setSubtitle(null);
+ }
+ }
+
+ @Override
+ public void onSongsChanged(List<DownloadFile> songs, DownloadFile currentPlaying, int currentPlayingIndex) {
+ currentPlayingSize = songs.size();
+
+ DownloadService downloadService = getDownloadService();
+ if(downloadService.isShufflePlayEnabled()) {
+ emptyTextView.setText(R.string.download_shuffle_loading);
+ }
+ else {
+ emptyTextView.setText(R.string.download_empty);
+ }
+
+ if(songListAdapter == null) {
+ songList = new ArrayList<>();
+ songList.addAll(songs);
+ playlistView.setAdapter(songListAdapter = new DownloadFileAdapter(context, songList, NowPlayingFragment.this));
+ } else {
+ songList.clear();
+ songList.addAll(songs);
+ songListAdapter.notifyDataSetChanged();
+ }
+
+ emptyTextView.setVisibility(songs.isEmpty() ? View.VISIBLE : View.GONE);
+ currentRevision = downloadService.getDownloadListUpdateRevision();
+
+ switch (downloadService.getRepeatMode()) {
+ case OFF:
+ if("light".equals(SubsonicActivity.getThemeName()) | "light_fullscreen".equals(SubsonicActivity.getThemeName())) {
+ repeatButton.setImageResource(R.drawable.media_repeat_off_light);
+ } else {
+ repeatButton.setImageResource(R.drawable.media_repeat_off);
+ }
+ break;
+ case ALL:
+ repeatButton.setImageResource(R.drawable.media_repeat_all);
+ break;
+ case SINGLE:
+ repeatButton.setImageResource(R.drawable.media_repeat_single);
+ break;
+ default:
+ break;
+ }
+
+ if(scrollWhenLoaded) {
+ scrollToCurrent();
+ scrollWhenLoaded = false;
+ }
+
+ setSubtitle(context.getResources().getString(R.string.download_playing_out_of, currentPlayingIndex, currentPlayingSize));
+ if(this.currentPlaying != currentPlaying) {
+ onSongChanged(currentPlaying, currentPlayingIndex);
+ }
+ }
+
+ @Override
+ public void onSongProgress(DownloadFile currentPlaying, int millisPlayed, Integer duration, boolean isSeekable) {
+ if (currentPlaying != null) {
+ int millisTotal = duration == null ? 0 : duration;
+
+ positionTextView.setText(Util.formatDuration(millisPlayed / 1000));
+ if(millisTotal > 0) {
+ durationTextView.setText(Util.formatDuration(millisTotal / 1000));
+ } else {
+ durationTextView.setText("-:--");
+ }
+ progressBar.setMax(millisTotal == 0 ? 100 : millisTotal); // Work-around for apparent bug.
+ if(!seekInProgress) {
+ progressBar.setProgress(millisPlayed);
+ }
+ progressBar.setEnabled(isSeekable);
+ } else {
+ positionTextView.setText("0:00");
+ durationTextView.setText("-:--");
+ progressBar.setProgress(0);
+ progressBar.setEnabled(false);
+ }
+ }
+
+ @Override
+ public void onStateUpdate(DownloadFile downloadFile, PlayerState playerState) {
+ switch (playerState) {
+ case DOWNLOADING:
+ if(currentPlaying != null) {
+ if(Util.isWifiRequiredForDownload(context)) {
+ statusTextView.setText(context.getResources().getString(R.string.download_playerstate_mobile_disabled));
+ } else {
+ long bytes = currentPlaying.getPartialFile().length();
+ statusTextView.setText(context.getResources().getString(R.string.download_playerstate_downloading, Util.formatLocalizedBytes(bytes, context)));
+ }
+ }
+ break;
+ case PREPARING:
+ statusTextView.setText(R.string.download_playerstate_buffering);
+ break;
+ default:
+ if(currentPlaying != null) {
+ String artist = "";
+ if(currentPlaying.getSong().getArtist() != null) {
+ artist = currentPlaying.getSong().getArtist() + " - ";
+ }
+ statusTextView.setText(artist + currentPlaying.getSong().getAlbum());
+ } else {
+ statusTextView.setText(null);
+ }
+ break;
+ }
+
+ switch (playerState) {
+ case STARTED:
+ pauseButton.setVisibility(View.VISIBLE);
+ stopButton.setVisibility(View.INVISIBLE);
+ startButton.setVisibility(View.INVISIBLE);
+ break;
+ case DOWNLOADING:
+ case PREPARING:
+ pauseButton.setVisibility(View.INVISIBLE);
+ stopButton.setVisibility(View.VISIBLE);
+ startButton.setVisibility(View.INVISIBLE);
+ break;
+ default:
+ pauseButton.setVisibility(View.INVISIBLE);
+ stopButton.setVisibility(View.INVISIBLE);
+ startButton.setVisibility(View.VISIBLE);
+ break;
+ }
+ }
}
diff --git a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
index 2e3217d2..cd22fb69 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
@@ -139,6 +139,7 @@ public class DownloadService extends Service {
private boolean removePlayed;
private boolean shufflePlay;
private boolean artistRadio;
+ private final List<OnSongChangedListener> onSongChangedListeners = new ArrayList<>();
private long revision;
private static DownloadService instance;
private String suggestedPlaylistName;
@@ -362,7 +363,6 @@ public class DownloadService extends Service {
}
}
setNextPlaying();
- revision++;
} else {
int size = size();
int index = getCurrentPlayingIndex();
@@ -378,8 +378,9 @@ public class DownloadService extends Service {
if(!autoplay && (size - 1) == index) {
setNextPlaying();
}
- revision++;
}
+ revision++;
+ onSongsChanged();
updateRemotePlaylist();
if(shuffle) {
@@ -543,6 +544,7 @@ public class DownloadService extends Service {
currentPlayingIndex = 0;
}
revision++;
+ onSongsChanged();
lifecycleSupport.serializeDownloadQueue();
updateRemotePlaylist();
setNextPlaying();
@@ -694,7 +696,7 @@ public class DownloadService extends Service {
reset();
downloadList.clear();
- revision++;
+ onSongsChanged();
if (currentDownloading != null && !backgroundDownloadList.contains(currentDownloading)) {
currentDownloading.cancelDownload();
currentDownloading = null;
@@ -733,6 +735,7 @@ public class DownloadService extends Service {
currentPlayingIndex = downloadList.indexOf(currentPlaying);
backgroundDownloadList.remove(downloadFile);
revision++;
+ onSongsChanged();
lifecycleSupport.serializeDownloadQueue();
updateRemotePlaylist();
if(downloadFile == nextPlaying) {
@@ -789,6 +792,7 @@ public class DownloadService extends Service {
Util.broadcastNewTrackInfo(this, null);
Notifications.hidePlayingNotification(this, this, handler);
}
+ onSongChanged();
}
synchronized void setNextPlaying() {
@@ -1284,6 +1288,7 @@ public class DownloadService extends Service {
positionCache.stop();
positionCache = null;
}
+ onStateUpdate();
}
private class PositionCache implements Runnable {
@@ -1318,6 +1323,7 @@ public class DownloadService extends Service {
subtractNextPosition = 0;
}
}
+ onSongProgress();
Thread.sleep(1000L);
}
catch(Exception e) {
@@ -1989,10 +1995,16 @@ public class DownloadService extends Service {
}
private synchronized void checkRemovePlayed() {
+ boolean changed = false;
while(currentPlayingIndex > 0) {
downloadList.remove(0);
currentPlayingIndex = downloadList.indexOf(currentPlaying);
+ changed = true;
+ }
+
+ if(changed) {
revision++;
+ onSongsChanged();
}
}
@@ -2030,6 +2042,7 @@ public class DownloadService extends Service {
currentPlayingIndex = downloadList.indexOf(currentPlaying);
if (revisionBefore != revision) {
+ onSongsChanged();
updateRemotePlaylist();
}
@@ -2071,6 +2084,7 @@ public class DownloadService extends Service {
currentPlayingIndex = downloadList.indexOf(currentPlaying);
if (revisionBefore != revision) {
+ onSongsChanged();
updateRemotePlaylist();
}
@@ -2338,6 +2352,71 @@ public class DownloadService extends Service {
}
}
+ public void addOnSongChangedListener(OnSongChangedListener listener) {
+ addOnSongChangedListener(listener, false);
+ }
+ public void addOnSongChangedListener(OnSongChangedListener listener, boolean run) {
+ int index = onSongChangedListeners.indexOf(listener);
+ if(index == -1) {
+ onSongChangedListeners.add(listener);
+ }
+
+ if(run) {
+ onSongsChanged();
+ onSongProgress();
+ onStateUpdate();
+ }
+ }
+ public void removeOnSongChangeListener(OnSongChangedListener listener) {
+ int index = onSongChangedListeners.indexOf(listener);
+ if(index != -1) {
+ onSongChangedListeners.remove(index);
+ }
+ }
+
+ private void onSongChanged() {
+ for(final OnSongChangedListener listener: onSongChangedListeners) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onSongChanged(currentPlaying, currentPlayingIndex);
+ }
+ });
+ }
+ }
+ private void onSongsChanged() {
+ for(final OnSongChangedListener listener: onSongChangedListeners) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onSongsChanged(downloadList, currentPlaying, currentPlayingIndex);
+ }
+ });
+ }
+ }
+ private void onSongProgress() {
+ final Integer duration = getPlayerDuration();
+ final boolean isSeekable = isSeekable();
+ for(final OnSongChangedListener listener: onSongChangedListeners) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onSongProgress(currentPlaying, cachedPosition, duration, isSeekable);
+ }
+ });
+ }
+ }
+ private void onStateUpdate() {
+ for(final OnSongChangedListener listener: onSongChangedListeners) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onStateUpdate(currentPlaying, playerState);
+ }
+ });
+ }
+ }
+
private class BufferTask extends SilentBackgroundTask<Void> {
private final DownloadFile downloadFile;
private final int position;
@@ -2441,4 +2520,11 @@ public class DownloadService extends Service {
return "CheckCompletionTask (" + downloadFile + ")";
}
}
+
+ public interface OnSongChangedListener {
+ void onSongChanged(DownloadFile currentPlaying, int currentPlayingIndex);
+ void onSongsChanged(List<DownloadFile> songs, DownloadFile currentPlaying, int currentPlayingIndex);
+ void onSongProgress(DownloadFile currentPlaying, int millisPlayed, Integer duration, boolean isSeekable);
+ void onStateUpdate(DownloadFile downloadFile, PlayerState playerState);
+ }
}