This helper will outlive the lifespan of a single instance of DemoDownloadService.
+ * It is static to avoid leaking the first DemoDownloadService instance.
+ */
+ private static final class TerminalStateNotificationHelper implements DownloadManager.Listener {
+
+ private final Context context;
+ private final DownloadNotificationHelper notificationHelper;
+
+ private int nextNotificationId;
+
+ public TerminalStateNotificationHelper(Context context, DownloadNotificationHelper notificationHelper, int firstNotificationId) {
+ this.context = context.getApplicationContext();
+ this.notificationHelper = notificationHelper;
+ nextNotificationId = firstNotificationId;
+ }
+
+ @Override
+ public void onDownloadChanged(DownloadManager downloadManager, Download download, @Nullable Exception finalException) {
+ Notification notification;
+
+ if (download.state == Download.STATE_COMPLETED) {
+ notification = notificationHelper.buildDownloadCompletedNotification(context, R.drawable.ic_done,null, Util.fromUtf8Bytes(download.request.data));
+ } else if (download.state == Download.STATE_FAILED) {
+ notification = notificationHelper.buildDownloadFailedNotification(context, R.drawable.ic_error, null, Util.fromUtf8Bytes(download.request.data));
+ } else {
+ return;
+ }
+
+ NotificationUtil.setNotification(context, nextNotificationId++, notification);
+ }
+ }
+}
diff --git a/app/src/main/java/com/cappielloantonio/play/service/MultiPlayer.java b/app/src/main/java/com/cappielloantonio/play/service/MultiPlayer.java
index 1bb3c878..4f6bccbb 100644
--- a/app/src/main/java/com/cappielloantonio/play/service/MultiPlayer.java
+++ b/app/src/main/java/com/cappielloantonio/play/service/MultiPlayer.java
@@ -7,7 +7,7 @@ import android.widget.Toast;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.service.playback.Playback;
+import com.cappielloantonio.play.interfaces.Playback;
import com.cappielloantonio.play.util.DownloadUtil;
import com.cappielloantonio.play.util.MusicUtil;
import com.cappielloantonio.play.util.PreferenceUtil;
@@ -18,7 +18,6 @@ import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
-import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.FileDataSource;
diff --git a/app/src/main/java/com/cappielloantonio/play/helper/MusicPlayerRemote.java b/app/src/main/java/com/cappielloantonio/play/service/MusicPlayerRemote.java
similarity index 99%
rename from app/src/main/java/com/cappielloantonio/play/helper/MusicPlayerRemote.java
rename to app/src/main/java/com/cappielloantonio/play/service/MusicPlayerRemote.java
index c56771fd..c34b9860 100644
--- a/app/src/main/java/com/cappielloantonio/play/helper/MusicPlayerRemote.java
+++ b/app/src/main/java/com/cappielloantonio/play/service/MusicPlayerRemote.java
@@ -1,4 +1,4 @@
-package com.cappielloantonio.play.helper;
+package com.cappielloantonio.play.service;
import android.app.Activity;
import android.content.ComponentName;
diff --git a/app/src/main/java/com/cappielloantonio/play/service/MusicService.java b/app/src/main/java/com/cappielloantonio/play/service/MusicService.java
index 4b014d58..ffa697e5 100644
--- a/app/src/main/java/com/cappielloantonio/play/service/MusicService.java
+++ b/app/src/main/java/com/cappielloantonio/play/service/MusicService.java
@@ -17,25 +17,23 @@ import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
-import android.preference.PreferenceManager;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
-import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.preference.Preference;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
+import com.cappielloantonio.play.broadcast.receiver.MediaButtonIntentReceiver;
import com.cappielloantonio.play.model.Playlist;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository;
-import com.cappielloantonio.play.service.notification.PlayingNotification;
-import com.cappielloantonio.play.service.playback.Playback;
+import com.cappielloantonio.play.ui.notification.PlayingNotification;
+import com.cappielloantonio.play.interfaces.Playback;
import com.cappielloantonio.play.util.PreferenceUtil;
import org.jellyfin.apiclient.interaction.EmptyResponse;
diff --git a/app/src/main/java/com/cappielloantonio/play/service/PlayDownloadService.java b/app/src/main/java/com/cappielloantonio/play/service/PlayDownloadService.java
deleted file mode 100644
index 96616961..00000000
--- a/app/src/main/java/com/cappielloantonio/play/service/PlayDownloadService.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2017 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.cappielloantonio.play.service;
-
-import android.app.Notification;
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.cappielloantonio.play.R;
-import com.cappielloantonio.play.util.DownloadUtil;
-import com.google.android.exoplayer2.offline.Download;
-import com.google.android.exoplayer2.offline.DownloadManager;
-import com.google.android.exoplayer2.offline.DownloadService;
-import com.google.android.exoplayer2.scheduler.Scheduler;
-import com.google.android.exoplayer2.ui.DownloadNotificationHelper;
-import com.google.android.exoplayer2.util.NotificationUtil;
-import com.google.android.exoplayer2.util.Util;
-
-import java.util.List;
-
-/**
- * A service for downloading media.
- */
-public class PlayDownloadService extends DownloadService {
-
- private static final int JOB_ID = 1;
- private static final int FOREGROUND_NOTIFICATION_ID = 1;
-
- public PlayDownloadService() {
- super(
- FOREGROUND_NOTIFICATION_ID,
- DEFAULT_FOREGROUND_NOTIFICATION_UPDATE_INTERVAL,
- DownloadUtil.DOWNLOAD_NOTIFICATION_CHANNEL_ID,
- R.string.exo_download_notification_channel_name,
- 0);
- }
-
- @Nullable
- @Override
- protected Scheduler getScheduler() {
- return null;
- }
-
- @Override
- @NonNull
- protected DownloadManager getDownloadManager() {
-
- DownloadManager downloadManager = DownloadUtil.getDownloadManager(/* context= */ this);
- DownloadNotificationHelper downloadNotificationHelper = DownloadUtil.getDownloadNotificationHelper(this);
- downloadManager.addListener(
- new TerminalStateNotificationHelper(
- this, downloadNotificationHelper, FOREGROUND_NOTIFICATION_ID + 1));
- return downloadManager;
- }
-
- @Override
- @NonNull
- protected Notification getForegroundNotification(@NonNull List This helper will outlive the lifespan of a single instance of DemoDownloadService.
- * It is static to avoid leaking the first DemoDownloadService instance.
- */
- private static final class TerminalStateNotificationHelper implements DownloadManager.Listener {
-
- private final Context context;
- private final DownloadNotificationHelper notificationHelper;
-
- private int nextNotificationId;
-
- public TerminalStateNotificationHelper(
- Context context, DownloadNotificationHelper notificationHelper, int firstNotificationId) {
- this.context = context.getApplicationContext();
- this.notificationHelper = notificationHelper;
- nextNotificationId = firstNotificationId;
- }
-
- @Override
- public void onDownloadChanged(
- DownloadManager downloadManager, Download download, @Nullable Exception finalException) {
- Notification notification;
- if (download.state == Download.STATE_COMPLETED) {
- notification =
- notificationHelper.buildDownloadCompletedNotification(
- context,
- R.drawable.ic_done,
- /* contentIntent= */ null,
- Util.fromUtf8Bytes(download.request.data));
- } else if (download.state == Download.STATE_FAILED) {
- notification =
- notificationHelper.buildDownloadFailedNotification(
- context,
- R.drawable.ic_done,
- /* contentIntent= */ null,
- Util.fromUtf8Bytes(download.request.data));
- } else {
- return;
- }
- NotificationUtil.setNotification(context, nextNotificationId++, notification);
- }
- }
-}
diff --git a/app/src/main/java/com/cappielloantonio/play/service/UnknownMediaSourceFactory.kt b/app/src/main/java/com/cappielloantonio/play/service/UnknownMediaSourceFactory.kt
deleted file mode 100644
index 82a5b65f..00000000
--- a/app/src/main/java/com/cappielloantonio/play/service/UnknownMediaSourceFactory.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.cappielloantonio.play.service
-
-import com.google.android.exoplayer2.MediaItem
-import com.google.android.exoplayer2.drm.DrmSessionManager
-import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
-import com.google.android.exoplayer2.source.MediaSource
-import com.google.android.exoplayer2.source.MediaSourceFactory
-import com.google.android.exoplayer2.source.ProgressiveMediaSource
-import com.google.android.exoplayer2.source.hls.HlsMediaSource
-import com.google.android.exoplayer2.upstream.*
-
-import kotlinx.coroutines.*
-
-import java.net.HttpURLConnection
-import java.net.URL
-
-class UnknownMediaSourceFactory(dataSourceFactory: DataSource.Factory) : MediaSourceFactory {
- private val hlsMediaSource : HlsMediaSource.Factory
- private val progressiveMediaSource : ProgressiveMediaSource.Factory
-
- private var loadErrorHandlingPolicy: LoadErrorHandlingPolicy
- override fun setDrmSessionManager(drmSessionManager: DrmSessionManager?): MediaSourceFactory {
- return this
- }
-
- override fun setDrmHttpDataSourceFactory(drmHttpDataSourceFactory: HttpDataSource.Factory?): MediaSourceFactory {
- return this
- }
-
- override fun setDrmUserAgent(drmUserAgent: String?): MediaSourceFactory {
- return this
- }
-
- override fun setLoadErrorHandlingPolicy(loadErrorHandlingPolicy: LoadErrorHandlingPolicy?): MediaSourceFactory {
- this.loadErrorHandlingPolicy = loadErrorHandlingPolicy!!
- return this
- }
-
- override fun getSupportedTypes(): IntArray {
- return intArrayOf()
- }
-
- override fun createMediaSource(mediaItem: MediaItem): MediaSource {
- val type: String? = runBlocking {
- httpGet(mediaItem.playbackProperties!!.uri.toString())
- }
-
- val sourceFactory: MediaSourceFactory = if (type == "application/x-mpegURL") {
- hlsMediaSource
- } else {
- progressiveMediaSource
- }
-
- return sourceFactory.createMediaSource(mediaItem)
- }
-
- private suspend fun httpGet(url: String?): String? {
- return withContext(Dispatchers.IO) {
- val request = URL(url)
- val conn = request.openConnection() as HttpURLConnection
-
- return@withContext conn.getHeaderField("Content-Type")
- }
- }
-
- init {
- hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory)
- progressiveMediaSource = ProgressiveMediaSource.Factory(dataSourceFactory, DefaultExtractorsFactory())
-
- loadErrorHandlingPolicy = DefaultLoadErrorHandlingPolicy()
- }
-}
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java b/app/src/main/java/com/cappielloantonio/play/ui/activity/MainActivity.java
similarity index 98%
rename from app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java
rename to app/src/main/java/com/cappielloantonio/play/ui/activity/MainActivity.java
index b7c84a7c..676bfe5c 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/activity/MainActivity.java
@@ -1,4 +1,4 @@
-package com.cappielloantonio.play.ui.activities;
+package com.cappielloantonio.play.ui.activity;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
@@ -18,9 +18,9 @@ import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.broadcast.receiver.ConnectivityStatusBroadcastReceiver;
import com.cappielloantonio.play.databinding.ActivityMainBinding;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.base.BaseActivity;
+import com.cappielloantonio.play.ui.activity.base.BaseActivity;
import com.cappielloantonio.play.ui.fragment.PlayerBottomSheetFragment;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.SyncUtil;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/activities/base/BaseActivity.java b/app/src/main/java/com/cappielloantonio/play/ui/activity/base/BaseActivity.java
similarity index 96%
rename from app/src/main/java/com/cappielloantonio/play/ui/activities/base/BaseActivity.java
rename to app/src/main/java/com/cappielloantonio/play/ui/activity/base/BaseActivity.java
index b7c3dad4..b84bf265 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/activities/base/BaseActivity.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/activity/base/BaseActivity.java
@@ -1,4 +1,4 @@
-package com.cappielloantonio.play.ui.activities.base;
+package com.cappielloantonio.play.ui.activity.base;
import android.Manifest;
import android.content.BroadcastReceiver;
@@ -19,11 +19,11 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import com.cappielloantonio.play.R;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.interfaces.MusicServiceEventListener;
import com.cappielloantonio.play.service.DownloadTracker;
import com.cappielloantonio.play.service.MusicService;
-import com.cappielloantonio.play.service.PlayDownloadService;
+import com.cappielloantonio.play.service.DownloaderService;
import com.cappielloantonio.play.util.DownloadUtil;
import com.google.android.exoplayer2.offline.DownloadService;
@@ -72,9 +72,9 @@ public class BaseActivity extends AppCompatActivity implements EasyPermissions.P
// action. Starting it in the background throws an exception if the app is in the background too
// (e.g. if device screen is locked).
try {
- DownloadService.start(this, PlayDownloadService.class);
+ DownloadService.start(this, DownloaderService.class);
} catch (IllegalStateException e) {
- DownloadService.startForeground(this, PlayDownloadService.class);
+ DownloadService.startForeground(this, DownloaderService.class);
}
}
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumCatalogueFragment.java
index e837f618..cf0baaf1 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumCatalogueFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumCatalogueFragment.java
@@ -2,21 +2,15 @@ package com.cappielloantonio.play.ui.fragment;
import android.annotation.SuppressLint;
import android.content.Context;
-import android.graphics.BlendMode;
-import android.graphics.BlendModeColorFilter;
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
-import android.widget.LinearLayout;
import android.widget.SearchView;
import androidx.annotation.NonNull;
@@ -27,18 +21,13 @@ import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.adapter.AlbumCatalogueAdapter;
import com.cappielloantonio.play.databinding.FragmentAlbumCatalogueBinding;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration;
-import com.cappielloantonio.play.repository.QueueRepository;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.viewmodel.AlbumCatalogueViewModel;
-import java.util.Collections;
-
public class AlbumCatalogueFragment extends Fragment {
private static final String TAG = "ArtistCatalogueFragment";
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumPageFragment.java
index e9a03ca4..8b040c31 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumPageFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumPageFragment.java
@@ -15,9 +15,9 @@ import com.cappielloantonio.play.App;
import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
import com.cappielloantonio.play.databinding.FragmentAlbumPageBinding;
import com.cappielloantonio.play.glide.CustomGlideRequest;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.repository.QueueRepository;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.DownloadUtil;
import com.cappielloantonio.play.viewmodel.AlbumPageViewModel;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistCatalogueFragment.java
index 3a60ca35..7788ba70 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistCatalogueFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistCatalogueFragment.java
@@ -3,7 +3,6 @@ package com.cappielloantonio.play.ui.fragment;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -26,7 +25,7 @@ import com.cappielloantonio.play.R;
import com.cappielloantonio.play.adapter.ArtistCatalogueAdapter;
import com.cappielloantonio.play.databinding.FragmentArtistCatalogueBinding;
import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.viewmodel.ArtistCatalogueViewModel;
public class ArtistCatalogueFragment extends Fragment {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistPageFragment.java
index 5ea8b527..e06a67d6 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistPageFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistPageFragment.java
@@ -2,7 +2,6 @@ package com.cappielloantonio.play.ui.fragment;
import android.graphics.BlendMode;
import android.graphics.BlendModeColorFilter;
-import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -21,10 +20,10 @@ import com.cappielloantonio.play.adapter.AlbumArtistPageAdapter;
import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
import com.cappielloantonio.play.databinding.FragmentArtistPageBinding;
import com.cappielloantonio.play.glide.CustomGlideRequest;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.viewmodel.ArtistPageViewModel;
import java.util.List;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java
index 76208bcf..47fcbe1b 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java
@@ -16,7 +16,7 @@ import com.cappielloantonio.play.R;
import com.cappielloantonio.play.databinding.FragmentFilterBinding;
import com.cappielloantonio.play.model.Genre;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.viewmodel.FilterViewModel;
import com.google.android.material.chip.Chip;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/GenreCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/GenreCatalogueFragment.java
index bd303caa..8e4c473a 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/GenreCatalogueFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/GenreCatalogueFragment.java
@@ -26,7 +26,7 @@ import com.cappielloantonio.play.adapter.GenreCatalogueAdapter;
import com.cappielloantonio.play.databinding.FragmentGenreCatalogueBinding;
import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.viewmodel.GenreCatalogueViewModel;
public class GenreCatalogueFragment extends Fragment {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeFragment.java
index 0788f09a..86fde6cb 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeFragment.java
@@ -1,14 +1,12 @@
package com.cappielloantonio.play.ui.fragment;
import android.os.Bundle;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
@@ -24,9 +22,7 @@ import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
import com.cappielloantonio.play.adapter.YearAdapter;
import com.cappielloantonio.play.databinding.FragmentHomeBinding;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.MainActivity;
-import com.cappielloantonio.play.util.MusicUtil;
-import com.cappielloantonio.play.util.PreferenceUtil;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.viewmodel.HomeViewModel;
public class HomeFragment extends Fragment {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LibraryFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LibraryFragment.java
index 71b988ef..88eefb1b 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LibraryFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LibraryFragment.java
@@ -1,11 +1,9 @@
package com.cappielloantonio.play.ui.fragment;
import android.os.Bundle;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -20,13 +18,11 @@ import androidx.viewpager2.widget.ViewPager2;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.adapter.AlbumAdapter;
import com.cappielloantonio.play.adapter.ArtistAdapter;
-import com.cappielloantonio.play.adapter.DiscoverSongAdapter;
import com.cappielloantonio.play.adapter.GenreAdapter;
import com.cappielloantonio.play.adapter.PlaylistAdapter;
import com.cappielloantonio.play.databinding.FragmentLibraryBinding;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.MainActivity;
-import com.cappielloantonio.play.util.MusicUtil;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.viewmodel.LibraryViewModel;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java
index 9f4491c6..cb7501a9 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java
@@ -13,7 +13,7 @@ import androidx.fragment.app.Fragment;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.databinding.FragmentLoginBinding;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.PreferenceUtil;
import org.jellyfin.apiclient.interaction.Response;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java
index 9bb70406..2ea0d3d7 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java
@@ -2,7 +2,6 @@ package com.cappielloantonio.play.ui.fragment;
import android.os.Bundle;
import android.os.Handler;
-import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -23,11 +22,11 @@ import com.cappielloantonio.play.adapter.PlayerNowPlayingSongAdapter;
import com.cappielloantonio.play.adapter.PlayerSongQueueAdapter;
import com.cappielloantonio.play.databinding.FragmentPlayerBottomSheetBinding;
import com.cappielloantonio.play.glide.CustomGlideRequest;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.helper.MusicProgressViewUpdateHelper;
import com.cappielloantonio.play.interfaces.MusicServiceEventListener;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.MusicUtil;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistCatalogueFragment.java
index b926da5c..05b35fa0 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistCatalogueFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistCatalogueFragment.java
@@ -18,23 +18,14 @@ import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
-import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.cappielloantonio.play.R;
-import com.cappielloantonio.play.adapter.GenreCatalogueAdapter;
-import com.cappielloantonio.play.adapter.PlaylistAdapter;
import com.cappielloantonio.play.adapter.PlaylistCatalogueAdapter;
-import com.cappielloantonio.play.databinding.FragmentGenreCatalogueBinding;
import com.cappielloantonio.play.databinding.FragmentPlaylistCatalogueBinding;
-import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration;
-import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.MainActivity;
-import com.cappielloantonio.play.viewmodel.GenreCatalogueViewModel;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.viewmodel.PlaylistCatalogueViewModel;
-import java.util.ArrayList;
-
public class PlaylistCatalogueFragment extends Fragment {
private static final String TAG = "GenreCatalogueFragment";;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java
index d8dad9f0..25d119cb 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java
@@ -14,11 +14,9 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
-import com.cappielloantonio.play.databinding.FragmentAlbumPageBinding;
import com.cappielloantonio.play.databinding.FragmentPlaylistPageBinding;
import com.cappielloantonio.play.glide.CustomGlideRequest;
-import com.cappielloantonio.play.ui.activities.MainActivity;
-import com.cappielloantonio.play.viewmodel.AlbumPageViewModel;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.viewmodel.PlaylistPageViewModel;
public class PlaylistPageFragment extends Fragment {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java
index aeae1ace..06adbeff 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java
@@ -22,7 +22,7 @@ import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
import com.cappielloantonio.play.databinding.FragmentSearchBinding;
import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.viewmodel.SearchViewModel;
import com.paulrybitskyi.persistentsearchview.adapters.model.SuggestionItem;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SettingsFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SettingsFragment.java
index 02d53bb4..1af90957 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SettingsFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SettingsFragment.java
@@ -1,16 +1,10 @@
package com.cappielloantonio.play.ui.fragment;
import android.os.Bundle;
-import android.util.Log;
-import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ListView;
-import android.widget.Toast;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
@@ -18,7 +12,7 @@ import androidx.preference.PreferenceFragmentCompat;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.helper.ThemeHelper;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.SyncUtil;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SongListPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SongListPageFragment.java
index ba15152a..19d2141f 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SongListPageFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SongListPageFragment.java
@@ -13,7 +13,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import com.cappielloantonio.play.adapter.SongResultSearchAdapter;
import com.cappielloantonio.play.databinding.FragmentSongListPageBinding;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.viewmodel.SongListPageViewModel;
public class SongListPageFragment extends Fragment {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SyncFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SyncFragment.java
index fa08f803..e5e7ee26 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SyncFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SyncFragment.java
@@ -12,7 +12,6 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
-import com.cappielloantonio.play.App;
import com.cappielloantonio.play.databinding.FragmentSyncBinding;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Album;
@@ -32,7 +31,7 @@ import com.cappielloantonio.play.repository.PlaylistRepository;
import com.cappielloantonio.play.repository.PlaylistSongRepository;
import com.cappielloantonio.play.repository.SongArtistRepository;
import com.cappielloantonio.play.repository.SongRepository;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.viewmodel.SyncViewModel;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java
index 6d7e1a93..42e7c22e 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java
@@ -16,20 +16,18 @@ import androidx.navigation.fragment.NavHostFragment;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Album;
import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.DownloadUtil;
-import com.cappielloantonio.play.util.MusicUtil;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.viewmodel.AlbumBottomSheetViewModel;
-import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import java.util.ArrayList;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java
index a7cd83ec..52e720a8 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java
@@ -15,17 +15,16 @@ import androidx.lifecycle.ViewModelProvider;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.viewmodel.ArtistBottomSheetViewModel;
-import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import java.util.ArrayList;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java
index 98825ab0..8fadd33f 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java
@@ -17,13 +17,13 @@ import androidx.navigation.fragment.NavHostFragment;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Album;
import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.DownloadUtil;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.SyncUtil;
diff --git a/app/src/main/java/com/cappielloantonio/play/service/notification/PlayingNotification.java b/app/src/main/java/com/cappielloantonio/play/ui/notification/PlayingNotification.java
similarity index 98%
rename from app/src/main/java/com/cappielloantonio/play/service/notification/PlayingNotification.java
rename to app/src/main/java/com/cappielloantonio/play/ui/notification/PlayingNotification.java
index 1f72ea6d..a4d01b24 100644
--- a/app/src/main/java/com/cappielloantonio/play/service/notification/PlayingNotification.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/notification/PlayingNotification.java
@@ -1,4 +1,4 @@
-package com.cappielloantonio.play.service.notification;
+package com.cappielloantonio.play.ui.notification;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -20,7 +20,7 @@ import androidx.media.app.NotificationCompat.MediaStyle;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.model.Song;
-import com.cappielloantonio.play.ui.activities.MainActivity;
+import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.service.MusicService;
import com.bumptech.glide.request.target.CustomTarget;
diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java
index 9f053853..91a6de4e 100644
--- a/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java
+++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java
@@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
-import com.cappielloantonio.play.helper.MusicPlayerRemote;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository;
diff --git a/app/src/main/res/drawable/ic_error.xml b/app/src/main/res/drawable/ic_error.xml
new file mode 100644
index 00000000..e5a5f372
--- /dev/null
+++ b/app/src/main/res/drawable/ic_error.xml
@@ -0,0 +1,9 @@
+