From 4389698d7f24a79febd14edba24173ef82295f35 Mon Sep 17 00:00:00 2001 From: Joshua Bahnsen Date: Sat, 25 Jan 2014 02:41:45 -0700 Subject: [PATCH] Remove menu alpha, ellipsize song titles, CenterCrop image in landscape, do not auto populate server on fresh install, change welcome text, add names to all threads, stop active ImageLoader threads when changing concurrency, show extension and bitrate for videos --- res/layout-land/download.xml | 2 +- res/layout/menu_main.xml | 37 ++++----- res/layout/song_details.xml | 4 +- res/layout/video_details.xml | 26 +++---- res/values/strings.xml | 2 +- res/values/styles.xml | 78 ++++++++++--------- .../androidapp/activity/SettingsActivity.java | 25 +++++- .../activity/SubsonicTabActivity.java | 8 +- .../service/DownloadServiceImpl.java | 9 ++- .../DownloadServiceLifecycleSupport.java | 3 + .../androidapp/service/JukeboxService.java | 19 +++-- .../androidapp/util/CacheCleaner.java | 3 + .../androidapp/util/ImageLoader.java | 27 ++++--- .../ultrasonic/androidapp/view/SongView.java | 10 ++- .../androidapp/view/UpdateView.java | 4 + 15 files changed, 157 insertions(+), 100 deletions(-) diff --git a/res/layout-land/download.xml b/res/layout-land/download.xml index 5a354b52..c6956e11 100644 --- a/res/layout-land/download.xml +++ b/res/layout-land/download.xml @@ -22,7 +22,7 @@ a:id="@+id/download_album_art_image" a:layout_width="wrap_content" a:layout_height="wrap_content" - a:scaleType="center" + a:scaleType="centerCrop" a:contentDescription="@string/albumArt"/> + android:id="@+id/menu_main" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + android:orientation="vertical" + android:alpha="1"> + android:text="@string/menu.navigation"/> + android:text="@string/button_bar.home"/> + android:text="@string/button_bar.browse"/> + android:text="@string/button_bar.search"/> + android:text="@string/button_bar.playlists"/> + android:text="@string/button_bar.shares"/> - + android:text="@string/button_bar.bookmarks"/> + + android:text="@string/button_bar.chat"/> + android:text="@string/button_bar.now_playing"/> + android:text="@string/menu.common"/> + android:text="@string/menu.settings"/> + android:text="@string/menu.about"/> + android:text="@string/menu.exit"/> \ No newline at end of file diff --git a/res/layout/song_details.xml b/res/layout/song_details.xml index 2568acb4..59290387 100644 --- a/res/layout/song_details.xml +++ b/res/layout/song_details.xml @@ -26,9 +26,9 @@ a:layout_gravity="left|center_vertical" a:layout_weight="1" a:drawablePadding="6dip" - a:ellipsize="marquee" + a:ellipsize="end" a:paddingLeft="4dip" - a:paddingRight="6dip" + a:paddingRight="2dip" a:singleLine="true" a:textAppearance="?android:attr/textAppearanceMedium"/> diff --git a/res/layout/video_details.xml b/res/layout/video_details.xml index ae02eef6..08ac014e 100644 --- a/res/layout/video_details.xml +++ b/res/layout/video_details.xml @@ -1,16 +1,16 @@ + a:layout_width="0dip" + a:layout_height="wrap_content" + a:layout_gravity="center_vertical" + a:layout_weight="1" + a:orientation="vertical"> + a:orientation="horizontal"> + a:textAppearance="?android:attr/textAppearanceMedium"/> + a:textAppearance="?android:attr/textAppearanceSmall"/> \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 8880666f..2a68266f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -95,7 +95,7 @@ Starred Songs Videos - Welcome to UltraSonic! The app is currently not configured. After you\'ve set up your personal server (available from subsonic.org), please go to Settings and change the configuration to connect to it. + Welcome to UltraSonic! The app is currently not configured. After you\'ve set up your personal server (available from subsonic.org), please click Add Server in Settings to connect to it. Welcome! About Common diff --git a/res/values/styles.xml b/res/values/styles.xml index 80b9672d..4c10b38e 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -1,29 +1,31 @@ + - + - + - + - - - + - - + + @@ -64,31 +66,31 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/SettingsActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/SettingsActivity.java index 5dc04b3e..ca47a469 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/activity/SettingsActivity.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/SettingsActivity.java @@ -48,6 +48,7 @@ import com.thejoshwa.ultrasonic.androidapp.service.MusicServiceFactory; import com.thejoshwa.ultrasonic.androidapp.util.Constants; import com.thejoshwa.ultrasonic.androidapp.util.ErrorDialog; import com.thejoshwa.ultrasonic.androidapp.util.FileUtil; +import com.thejoshwa.ultrasonic.androidapp.util.ImageLoader; import com.thejoshwa.ultrasonic.androidapp.util.ModalBackgroundTask; import com.thejoshwa.ultrasonic.androidapp.util.TimeSpanPreference; import com.thejoshwa.ultrasonic.androidapp.util.Util; @@ -102,7 +103,7 @@ public class SettingsActivity extends PreferenceResultActivity implements Shared public MenuDrawer menuDrawer; private int activePosition = 1; private int menuActiveViewId; - private int activeServers = 3; + private int activeServers; View chatMenuItem; View bookmarksMenuItem; View sharesMenuItem; @@ -224,7 +225,7 @@ public class SettingsActivity extends PreferenceResultActivity implements Shared } settings = PreferenceManager.getDefaultSharedPreferences(this); - activeServers = settings.getInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, 3); + activeServers = settings.getInt(Constants.PREFERENCES_KEY_ACTIVE_SERVERS, 0); serversCategory = (PreferenceCategory) findPreference(Constants.PREFERENCES_KEY_SERVERS_KEY); @@ -516,6 +517,10 @@ public class SettingsActivity extends PreferenceResultActivity implements Shared { setBluetoothPreferences(sharedPreferences.getBoolean(key, true)); } + else if (Constants.PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY.equals(key)) + { + setImageLoaderConcurrency(Integer.parseInt(sharedPreferences.getString(key, "5"))); + } } private void update() @@ -567,6 +572,22 @@ public class SettingsActivity extends PreferenceResultActivity implements Shared } } + private static void setImageLoaderConcurrency(int concurrency) + { + SubsonicTabActivity instance = SubsonicTabActivity.getInstance(); + + if (instance != null) + { + ImageLoader imageLoader = instance.getImageLoader(); + + if (imageLoader != null) + { + imageLoader.stopImageLoader(); + imageLoader.setConcurrency(concurrency); + } + } + } + private void setHideMedia(boolean hide) { File nomediaDir = new File(FileUtil.getUltraSonicDirectory(), ".nomedia"); diff --git a/src/com/thejoshwa/ultrasonic/androidapp/activity/SubsonicTabActivity.java b/src/com/thejoshwa/ultrasonic/androidapp/activity/SubsonicTabActivity.java index 82847ddd..1343fdef 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/activity/SubsonicTabActivity.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/activity/SubsonicTabActivity.java @@ -349,16 +349,11 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen new AsyncTask() { - @Override - protected void onPostExecute(String[] result) - { - super.onPostExecute(result); - } - @SuppressLint("NewApi") @Override protected String[] doInBackground(Void... params) { + Thread.currentThread().setName("showNotification"); RemoteViews notificationView = notification.contentView; RemoteViews bigNotificationView = null; @@ -455,7 +450,6 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen public void hidePlayingNotification(final Handler handler, final DownloadServiceImpl downloadService) { - currentSong = null; // Remove notification and remove the service from the foreground diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java index 9717303f..9b1c546d 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceImpl.java @@ -179,6 +179,8 @@ public class DownloadServiceImpl extends Service implements DownloadService @Override public void run() { + Thread.currentThread().setName("DownloadServiceImpl"); + Looper.prepare(); if (mediaPlayer != null) @@ -2172,6 +2174,8 @@ public class DownloadServiceImpl extends Service implements DownloadService @Override public void run() { + Thread.currentThread().setName("PositionCache"); + // Stop checking position before the song reaches completion while (isRunning) { @@ -2181,7 +2185,8 @@ public class DownloadServiceImpl extends Service implements DownloadService { cachedPosition = mediaPlayer.getCurrentPosition(); } - Thread.sleep(200L); + + Thread.sleep(50L); } catch (Exception e) { @@ -2211,6 +2216,8 @@ public class DownloadServiceImpl extends Service implements DownloadService @Override public void execute() { + Thread.currentThread().setName("CheckCompletionTask"); + if (downloadFile == null) { return; diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceLifecycleSupport.java b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceLifecycleSupport.java index a62427fe..1957b5a6 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceLifecycleSupport.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/DownloadServiceLifecycleSupport.java @@ -367,6 +367,7 @@ public class DownloadServiceLifecycleSupport { try { + Thread.currentThread().setName("SerializeTask"); serializeDownloadQueueNow(); } finally @@ -385,6 +386,7 @@ public class DownloadServiceLifecycleSupport { try { + Thread.currentThread().setName("DeserializeTask"); lock.lock(); deserializeDownloadQueueNow(); setup.set(true); @@ -393,6 +395,7 @@ public class DownloadServiceLifecycleSupport { lock.unlock(); } + return null; } } diff --git a/src/com/thejoshwa/ultrasonic/androidapp/service/JukeboxService.java b/src/com/thejoshwa/ultrasonic/androidapp/service/JukeboxService.java index f78834de..8a66c364 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/service/JukeboxService.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/service/JukeboxService.java @@ -41,6 +41,7 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; /** @@ -64,7 +65,7 @@ public class JukeboxService private JukeboxStatus jukeboxStatus; private float gain = 0.5f; private VolumeToast volumeToast; - private boolean running = false; + private AtomicBoolean running = new AtomicBoolean(); private Thread serviceThread; // TODO: Report warning if queue fills up. @@ -80,18 +81,24 @@ public class JukeboxService public void startJukeboxService() { - if (running) return; + if (running.get()) + { + return; + } - running = true; + running.set(true); startProcessTasks(); } public void stopJukeboxService() { - running = false; + running.set(false); Util.sleepQuietly(1000); - if (serviceThread != null) serviceThread.interrupt(); + if (serviceThread != null) + { + serviceThread.interrupt(); + } } private void startProcessTasks() @@ -136,7 +143,7 @@ public class JukeboxService private void processTasks() { - while (running) + while (running.get()) { JukeboxTask task = null; diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java b/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java index e6628c65..48961d59 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/CacheCleaner.java @@ -239,6 +239,7 @@ public class CacheCleaner try { + Thread.currentThread().setName("BackgroundCleanup"); List files = new ArrayList(); List dirs = new ArrayList(); @@ -272,6 +273,7 @@ public class CacheCleaner try { + Thread.currentThread().setName("BackgroundSpaceCleanup"); List files = new ArrayList(); List dirs = new ArrayList(); findCandidatesForDeletion(FileUtil.getMusicDirectory(context), files, dirs); @@ -300,6 +302,7 @@ public class CacheCleaner { try { + Thread.currentThread().setName("BackgroundPlaylistsCleanup"); String server = Util.getServerName(context); SortedSet playlistFiles = FileUtil.listFiles(FileUtil.getPlaylistDirectory(server)); List playlists = params[0]; diff --git a/src/com/thejoshwa/ultrasonic/androidapp/util/ImageLoader.java b/src/com/thejoshwa/ultrasonic/androidapp/util/ImageLoader.java index cfb887fe..d433b5f5 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/util/ImageLoader.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/util/ImageLoader.java @@ -40,6 +40,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicBoolean; /** * Asynchronous loading of images, with caching. @@ -50,7 +51,6 @@ import java.util.concurrent.LinkedBlockingQueue; */ public class ImageLoader implements Runnable { - private static final String TAG = ImageLoader.class.getSimpleName(); private final LRUCache cache = new LRUCache(150); @@ -59,8 +59,8 @@ public class ImageLoader implements Runnable private final int imageSizeLarge; private Bitmap largeUnknownImage; private Context context; - private Collection threads = new ArrayList(); - private boolean running = false; + private Collection threads; + private AtomicBoolean running = new AtomicBoolean(); private int concurrency; public ImageLoader(Context context, int concurrency) @@ -86,16 +86,23 @@ public class ImageLoader implements Runnable public synchronized boolean isRunning() { - return running && !threads.isEmpty(); + return running.get() && !threads.isEmpty(); + } + + public void setConcurrency(int concurrency) + { + this.concurrency = concurrency; } public void startImageLoader() { - running = true; + running.set(true); + + threads = new ArrayList(this.concurrency); for (int i = 0; i < this.concurrency; i++) { - Thread thread = new Thread(this, "ImageLoader"); + Thread thread = new Thread(this, String.format("ImageLoader [%d]", i)); threads.add(thread); thread.start(); } @@ -110,7 +117,8 @@ public class ImageLoader implements Runnable thread.interrupt(); } - running = false; + running.set(false); + threads.clear(); } private void createLargeUnknownImage(Context context) @@ -263,7 +271,7 @@ public class ImageLoader implements Runnable @Override public void run() { - while (running) + while (running.get()) { try { @@ -272,7 +280,8 @@ public class ImageLoader implements Runnable } catch (InterruptedException ignored) { - + running.set(false); + break; } catch (Throwable x) { diff --git a/src/com/thejoshwa/ultrasonic/androidapp/view/SongView.java b/src/com/thejoshwa/ultrasonic/androidapp/view/SongView.java index 0a524807..f8982346 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/view/SongView.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/view/SongView.java @@ -197,7 +197,15 @@ public class SongView extends UpdateView implements Checkable } } - viewHolder.title.setText(song.getTitle()); + StringBuilder title = new StringBuilder(60); + title.append(song.getTitle()); + + if (song.isVideo() && Util.shouldDisplayBitrateWithArtist(this.context)) + { + title.append(" (").append(String.format(this.context.getString(R.string.song_details_all), bitRate == null ? "" : String.format("%s ", bitRate), fileFormat)).append(')'); + } + + viewHolder.title.setText(title); if (viewHolder.artist != null) { diff --git a/src/com/thejoshwa/ultrasonic/androidapp/view/UpdateView.java b/src/com/thejoshwa/ultrasonic/androidapp/view/UpdateView.java index b6c3dab9..21dac706 100644 --- a/src/com/thejoshwa/ultrasonic/androidapp/view/UpdateView.java +++ b/src/com/thejoshwa/ultrasonic/androidapp/view/UpdateView.java @@ -62,6 +62,7 @@ public class UpdateView extends LinearLayout @Override public void run() { + Thread.currentThread().setName("startUpdater"); Looper.prepare(); backgroundHandler = new Handler(Looper.myLooper()); uiHandler.post(updateRunnable); @@ -110,6 +111,7 @@ public class UpdateView extends LinearLayout { Log.w(TAG, "Error when updating song views.", x); } + uiHandler.postDelayed(updateRunnable, Util.getViewRefreshInterval(context)); } }; @@ -121,6 +123,8 @@ public class UpdateView extends LinearLayout { try { + Thread.currentThread().setName("updateAllLive-Background"); + for (UpdateView view : views) { view.updateBackground();