aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java')
-rw-r--r--app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java24
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/DownloadService.java133
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/Notifications.java68
3 files changed, 143 insertions, 82 deletions
diff --git a/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java b/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java
index 0ee16723..f4238c99 100644
--- a/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java
+++ b/app/src/main/java/github/daneren2005/dsub/provider/DLNARouteProvider.java
@@ -228,7 +228,9 @@ public class DLNARouteProvider extends MediaRouteProvider {
removing.remove(id);
return;
}
- adding.add(id);
+ synchronized (adding) {
+ adding.add(id);
+ }
if(device.getType().getType().equals("MediaRenderer") && device instanceof RemoteDevice) {
try {
@@ -255,21 +257,35 @@ public class DLNARouteProvider extends MediaRouteProvider {
broadcastDescriptors();
}
});
- adding.remove(id);
+
+ synchronized (adding) {
+ if (adding.contains(id)) {
+ adding.remove(id);
+ }
+ }
}
@Override
public void failure(ActionInvocation actionInvocation, UpnpResponse upnpResponse, String s) {
Log.w(TAG, "Failed to get default volume for DLNA route");
Log.w(TAG, "Reason: " + s);
- adding.remove(id);
+
+ synchronized (adding) {
+ if (adding.contains(id)) {
+ adding.remove(id);
+ }
+ }
}
});
} catch(Exception e) {
Log.e(TAG, "Failed to add device", e);
}
} else {
- adding.remove(id);
+ synchronized (adding) {
+ if(adding.contains(id)) {
+ adding.remove(id);
+ }
+ }
}
}
private void deviceRemoved(Device device) {
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 c5caad26..a4ca705c 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
@@ -68,6 +68,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.concurrent.CopyOnWriteArrayList;
import android.annotation.TargetApi;
import android.app.Service;
@@ -154,7 +155,7 @@ public class DownloadService extends Service {
private boolean removePlayed;
private boolean shufflePlay;
private boolean artistRadio;
- private final List<OnSongChangedListener> onSongChangedListeners = new ArrayList<>();
+ private final CopyOnWriteArrayList<OnSongChangedListener> onSongChangedListeners = new CopyOnWriteArrayList<>();
private long revision;
private static DownloadService instance;
private String suggestedPlaylistName;
@@ -2800,12 +2801,7 @@ public class DownloadService extends Service {
addOnSongChangedListener(listener, false);
}
public void addOnSongChangedListener(OnSongChangedListener listener, boolean run) {
- synchronized(onSongChangedListeners) {
- int index = onSongChangedListeners.indexOf(listener);
- if (index == -1) {
- onSongChangedListeners.add(listener);
- }
- }
+ onSongChangedListeners.addIfAbsent(listener);
if(run) {
if(mediaPlayerHandler != null) {
@@ -2824,56 +2820,47 @@ public class DownloadService extends Service {
}
}
public void removeOnSongChangeListener(OnSongChangedListener listener) {
- synchronized(onSongChangedListeners) {
- int index = onSongChangedListeners.indexOf(listener);
- if (index != -1) {
- onSongChangedListeners.remove(index);
- }
- }
+ onSongChangedListeners.remove(listener);
}
private void onSongChanged() {
final long atRevision = revision;
- synchronized(onSongChangedListeners) {
- final boolean shouldFastForward = shouldFastForward();
- for (final OnSongChangedListener listener : onSongChangedListeners) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if (revision == atRevision && instance != null) {
- listener.onSongChanged(currentPlaying, currentPlayingIndex, shouldFastForward);
+ final boolean shouldFastForward = shouldFastForward();
+ for (final OnSongChangedListener listener : onSongChangedListeners) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (revision == atRevision && instance != null) {
+ listener.onSongChanged(currentPlaying, currentPlayingIndex, shouldFastForward);
- MusicDirectory.Entry entry = currentPlaying != null ? currentPlaying.getSong() : null;
- listener.onMetadataUpdate(entry, METADATA_UPDATED_ALL);
- }
+ MusicDirectory.Entry entry = currentPlaying != null ? currentPlaying.getSong() : null;
+ listener.onMetadataUpdate(entry, METADATA_UPDATED_ALL);
}
- });
- }
+ }
+ });
+ }
- if (mediaPlayerHandler != null && !onSongChangedListeners.isEmpty()) {
- mediaPlayerHandler.post(new Runnable() {
- @Override
- public void run() {
- onSongProgress();
- }
- });
- }
+ if (mediaPlayerHandler != null && !onSongChangedListeners.isEmpty()) {
+ mediaPlayerHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ onSongProgress();
+ }
+ });
}
}
private void onSongsChanged() {
final long atRevision = revision;
- synchronized(onSongChangedListeners) {
- final boolean shouldFastForward = shouldFastForward();
- for (final OnSongChangedListener listener : onSongChangedListeners) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if (revision == atRevision && instance != null) {
- listener.onSongsChanged(downloadList, currentPlaying, currentPlayingIndex, shouldFastForward);
- }
+ final boolean shouldFastForward = shouldFastForward();
+ for (final OnSongChangedListener listener : onSongChangedListeners) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (revision == atRevision && instance != null) {
+ listener.onSongsChanged(downloadList, currentPlaying, currentPlayingIndex, shouldFastForward);
}
- });
- }
+ }
+ });
}
}
@@ -2888,17 +2875,15 @@ public class DownloadService extends Service {
final int index = getCurrentPlayingIndex();
final int queueSize = size();
- synchronized(onSongChangedListeners) {
- for (final OnSongChangedListener listener : onSongChangedListeners) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if (revision == atRevision && instance != null) {
- listener.onSongProgress(currentPlaying, position, duration, isSeekable);
- }
+ for (final OnSongChangedListener listener : onSongChangedListeners) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (revision == atRevision && instance != null) {
+ listener.onSongProgress(currentPlaying, position, duration, isSeekable);
}
- });
- }
+ }
+ });
}
if(manual) {
@@ -2921,35 +2906,31 @@ public class DownloadService extends Service {
}
private void onStateUpdate() {
final long atRevision = revision;
- synchronized(onSongChangedListeners) {
- for (final OnSongChangedListener listener : onSongChangedListeners) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if (revision == atRevision && instance != null) {
- listener.onStateUpdate(currentPlaying, playerState);
- }
+ for (final OnSongChangedListener listener : onSongChangedListeners) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (revision == atRevision && instance != null) {
+ listener.onStateUpdate(currentPlaying, playerState);
}
- });
- }
+ }
+ });
}
}
public void onMetadataUpdate() {
onMetadataUpdate(METADATA_UPDATED_ALL);
}
public void onMetadataUpdate(final int updateType) {
- synchronized(onSongChangedListeners) {
- for (final OnSongChangedListener listener : onSongChangedListeners) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if (instance != null) {
- MusicDirectory.Entry entry = currentPlaying != null ? currentPlaying.getSong() : null;
- listener.onMetadataUpdate(entry, updateType);
- }
+ for (final OnSongChangedListener listener : onSongChangedListeners) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (instance != null) {
+ MusicDirectory.Entry entry = currentPlaying != null ? currentPlaying.getSong() : null;
+ listener.onMetadataUpdate(entry, updateType);
}
- });
- }
+ }
+ });
}
handler.post(new Runnable() {
diff --git a/app/src/main/java/github/daneren2005/dsub/util/Notifications.java b/app/src/main/java/github/daneren2005/dsub/util/Notifications.java
index 750ab40c..428c33e0 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/Notifications.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/Notifications.java
@@ -15,7 +15,9 @@
package github.daneren2005.dsub.util;
+import android.annotation.TargetApi;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -56,11 +58,24 @@ public final class Notifications {
private static boolean downloadForeground = false;
private static boolean persistentPlayingShowing = false;
+ private static NotificationChannel playingChannel;
+ private static NotificationChannel downloadingChannel;
+ private static NotificationChannel syncChannel;
+
private final static Pair<Integer, Integer> NOTIFICATION_TEXT_COLORS = new Pair<Integer, Integer>();
public static void showPlayingNotification(final Context context, final DownloadService downloadService, final Handler handler, MusicDirectory.Entry song) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ getPlayingNotificationChannel(context);
+ }
+
// Set the icon, scrolling text and timestamp
- final Notification notification = new Notification(R.drawable.stat_notify_playing, song.getTitle(), System.currentTimeMillis());
+ final Notification notification = new NotificationCompat.Builder(context)
+ .setSmallIcon(R.drawable.stat_notify_playing)
+ .setTicker(song.getTitle())
+ .setWhen(System.currentTimeMillis())
+ .setChannelId("now-playing-channel")
+ .build();
final boolean playing = downloadService.getPlayerState() == PlayerState.STARTED;
if(playing) {
@@ -331,7 +346,24 @@ public final class Notifications {
DSubWidgetProvider.notifyInstances(context, downloadService, false);
}
+ @TargetApi(Build.VERSION_CODES.O)
+ private static NotificationChannel getPlayingNotificationChannel(Context context) {
+ if(playingChannel == null) {
+ playingChannel = new NotificationChannel("now-playing-channel", "Now Playing", NotificationManager.IMPORTANCE_LOW);
+ playingChannel.setDescription("Now playing notification");
+
+ NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(playingChannel);
+ }
+
+ return playingChannel;
+ }
+
public static void showDownloadingNotification(final Context context, final DownloadService downloadService, Handler handler, DownloadFile file, int size) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ getDownloadingNotificationChannel(context);
+ }
+
Intent cancelIntent = new Intent(context, DownloadService.class);
cancelIntent.setAction(DownloadService.CANCEL_DOWNLOADS);
PendingIntent cancelPI = PendingIntent.getService(context, 0, cancelIntent, 0);
@@ -356,7 +388,8 @@ public final class Notifications {
.setOngoing(true)
.addAction(R.drawable.notification_close,
context.getResources().getString(R.string.common_cancel),
- cancelPI);
+ cancelPI)
+ .setChannelId("downloading-channel");
Intent notificationIntent = new Intent(context, SubsonicFragmentActivity.class);
notificationIntent.putExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW, true);
@@ -395,6 +428,19 @@ public final class Notifications {
}
}
+ @TargetApi(Build.VERSION_CODES.O)
+ private static NotificationChannel getDownloadingNotificationChannel(Context context) {
+ if(downloadingChannel == null) {
+ downloadingChannel = new NotificationChannel("downloading-channel", "Downloading Notification", NotificationManager.IMPORTANCE_LOW);
+ downloadingChannel.setDescription("Ongoing downloading notification to keep the service alive");
+
+ NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(downloadingChannel);
+ }
+
+ return downloadingChannel;
+ }
+
public static void showSyncNotification(final Context context, int stringId, String extra) {
showSyncNotification(context, stringId, extra, null);
}
@@ -404,6 +450,10 @@ public final class Notifications {
extra = "";
}
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ getSyncNotificationChannel(context);
+ }
+
NotificationCompat.Builder builder;
builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.stat_notify_sync)
@@ -413,6 +463,7 @@ public final class Notifications {
.setOngoing(false)
.setGroup(NOTIFICATION_SYNC_GROUP)
.setPriority(NotificationCompat.PRIORITY_LOW)
+ .setChannelId("sync-channel")
.setAutoCancel(true);
Intent notificationIntent = new Intent(context, SubsonicFragmentActivity.class);
@@ -449,4 +500,17 @@ public final class Notifications {
notificationManager.notify(stringId, builder.build());
}
}
+
+ @TargetApi(Build.VERSION_CODES.O)
+ private static NotificationChannel getSyncNotificationChannel(Context context) {
+ if(syncChannel == null) {
+ syncChannel = new NotificationChannel("sync-channel", "Sync Notifications", NotificationManager.IMPORTANCE_MIN);
+ syncChannel.setDescription("Sync notifications");
+
+ NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(syncChannel);
+ }
+
+ return syncChannel;
+ }
}