Clover Coverage Report - Subsonic-Android Coverage Report
Coverage timestamp: ven dic 19 2014 17:57:13 EST
../../../../../img/srcFileCovDistChart9.png 32% of files have more coverage
433   884   134   8,17
104   758   0,31   26,5
53     2,53  
2    
This report was generated with an evaluation server license. Purchase Clover or configure your license.
 
  DownloadActivity       Line # 78 425 130 87,5% 0.87543255
  DownloadActivity.SongListAdapter       Line # 791 8 4 100% 1.0
 
No Tests
 
1    /*
2    This file is part of Subsonic.
3   
4    Subsonic is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8   
9    Subsonic is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12    GNU General Public License for more details.
13   
14    You should have received a copy of the GNU General Public License
15    along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
16   
17    Copyright 2009 (C) Sindre Mehus
18    */
19    package net.sourceforge.subsonic.androidapp.activity;
20   
21    import java.text.DateFormat;
22    import java.text.SimpleDateFormat;
23    import java.util.Date;
24    import java.util.LinkedList;
25    import java.util.List;
26    import java.util.concurrent.Executors;
27    import java.util.concurrent.ScheduledExecutorService;
28    import java.util.concurrent.TimeUnit;
29   
30    import android.app.AlertDialog;
31    import android.app.Dialog;
32    import android.content.DialogInterface;
33    import android.content.Intent;
34    import android.graphics.Color;
35    import android.graphics.Typeface;
36    import android.os.Bundle;
37    import android.os.Handler;
38    import android.view.ContextMenu;
39    import android.view.Display;
40    import android.view.GestureDetector;
41    import android.view.GestureDetector.OnGestureListener;
42    import android.view.LayoutInflater;
43    import android.view.Menu;
44    import android.view.MenuInflater;
45    import android.view.MenuItem;
46    import android.view.MotionEvent;
47    import android.view.View;
48    import android.view.ViewGroup;
49    import android.view.WindowManager;
50    import android.view.animation.AnimationUtils;
51    import android.widget.AdapterView;
52    import android.widget.ArrayAdapter;
53    import android.widget.Button;
54    import android.widget.EditText;
55    import android.widget.ImageButton;
56    import android.widget.ImageView;
57    import android.widget.LinearLayout;
58    import android.widget.ListView;
59    import android.widget.TextView;
60    import android.widget.ViewFlipper;
61    import net.sourceforge.subsonic.androidapp.R;
62    import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
63    import net.sourceforge.subsonic.androidapp.domain.PlayerState;
64    import net.sourceforge.subsonic.androidapp.domain.RepeatMode;
65    import net.sourceforge.subsonic.androidapp.service.DownloadFile;
66    import net.sourceforge.subsonic.androidapp.service.DownloadService;
67    import net.sourceforge.subsonic.androidapp.service.MusicService;
68    import net.sourceforge.subsonic.androidapp.service.MusicServiceFactory;
69    import net.sourceforge.subsonic.androidapp.util.Constants;
70    import net.sourceforge.subsonic.androidapp.util.HorizontalSlider;
71    import net.sourceforge.subsonic.androidapp.util.SilentBackgroundTask;
72    import net.sourceforge.subsonic.androidapp.util.SongView;
73    import net.sourceforge.subsonic.androidapp.util.Util;
74    import net.sourceforge.subsonic.androidapp.view.VisualizerView;
75   
76    import static net.sourceforge.subsonic.androidapp.domain.PlayerState.*;
77   
 
78    public class DownloadActivity extends SubsonicTabActivity implements OnGestureListener {
79   
80    private static final int DIALOG_SAVE_PLAYLIST = 100;
81    private static final int PERCENTAGE_OF_SCREEN_FOR_SWIPE = 5;
82    private static final int COLOR_BUTTON_ENABLED = Color.rgb(0, 153, 204);
83    private static final int COLOR_BUTTON_DISABLED = Color.rgb(164, 166, 158);
84   
85    private ViewFlipper playlistFlipper;
86    private ViewFlipper buttonBarFlipper;
87    private TextView emptyTextView;
88    private TextView songTitleTextView;
89    private TextView albumTextView;
90    private TextView artistTextView;
91    private ImageView albumArtImageView;
92    private ListView playlistView;
93    private TextView positionTextView;
94    private TextView durationTextView;
95    private TextView statusTextView;
96    private HorizontalSlider progressBar;
97    private View previousButton;
98    private View nextButton;
99    private View pauseButton;
100    private View stopButton;
101    private View startButton;
102    private View shuffleButton;
103    private ImageButton repeatButton;
104    private Button equalizerButton;
105    private Button visualizerButton;
106    private Button jukeboxButton;
107    private View toggleListButton;
108    private ScheduledExecutorService executorService;
109    private DownloadFile currentPlaying;
110    private long currentRevision;
111    private EditText playlistNameView;
112    private GestureDetector gestureScanner;
113    private int swipeDistance;
114    private int swipeVelocity;
115    private VisualizerView visualizerView;
116   
117    /**
118    * Called when the activity is first created.
119    */
 
120  6 toggle @Override
121    public void onCreate(Bundle savedInstanceState) {
122  6 super.onCreate(savedInstanceState);
123  6 setContentView(R.layout.download);
124   
125  6 WindowManager w = getWindowManager();
126  6 Display d = w.getDefaultDisplay();
127  6 swipeDistance = (d.getWidth() + d.getHeight()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100;
128  6 swipeVelocity = (d.getWidth() + d.getHeight()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100;
129  6 gestureScanner = new GestureDetector(this);
130   
131  6 playlistFlipper = (ViewFlipper) findViewById(R.id.download_playlist_flipper);
132  6 buttonBarFlipper = (ViewFlipper) findViewById(R.id.download_button_bar_flipper);
133  6 emptyTextView = (TextView) findViewById(R.id.download_empty);
134  6 songTitleTextView = (TextView) findViewById(R.id.download_song_title);
135  6 albumTextView = (TextView) findViewById(R.id.download_album);
136  6 artistTextView = (TextView) findViewById(R.id.download_artist);
137  6 albumArtImageView = (ImageView) findViewById(R.id.download_album_art_image);
138  6 positionTextView = (TextView) findViewById(R.id.download_position);
139  6 durationTextView = (TextView) findViewById(R.id.download_duration);
140  6 statusTextView = (TextView) findViewById(R.id.download_status);
141  6 progressBar = (HorizontalSlider) findViewById(R.id.download_progress_bar);
142  6 playlistView = (ListView) findViewById(R.id.download_list);
143  6 previousButton = findViewById(R.id.download_previous);
144  6 nextButton = findViewById(R.id.download_next);
145  6 pauseButton = findViewById(R.id.download_pause);
146  6 stopButton = findViewById(R.id.download_stop);
147  6 startButton = findViewById(R.id.download_start);
148  6 shuffleButton = findViewById(R.id.download_shuffle);
149  6 repeatButton = (ImageButton) findViewById(R.id.download_repeat);
150  6 equalizerButton = (Button) findViewById(R.id.download_equalizer);
151  6 visualizerButton = (Button) findViewById(R.id.download_visualizer);
152  6 jukeboxButton = (Button) findViewById(R.id.download_jukebox);
153  6 LinearLayout visualizerViewLayout = (LinearLayout) findViewById(R.id.download_visualizer_view_layout);
154   
155  6 toggleListButton = findViewById(R.id.download_toggle_list);
156   
157  6 View.OnTouchListener touchListener = new View.OnTouchListener() {
 
158  159 toggle @Override
159    public boolean onTouch(View v, MotionEvent me) {
160  159 return gestureScanner.onTouchEvent(me);
161    }
162    };
163  6 previousButton.setOnTouchListener(touchListener);
164  6 nextButton.setOnTouchListener(touchListener);
165  6 pauseButton.setOnTouchListener(touchListener);
166  6 stopButton.setOnTouchListener(touchListener);
167  6 startButton.setOnTouchListener(touchListener);
168  6 equalizerButton.setOnTouchListener(touchListener);
169  6 visualizerButton.setOnTouchListener(touchListener);
170  6 jukeboxButton.setOnTouchListener(touchListener);
171  6 buttonBarFlipper.setOnTouchListener(touchListener);
172  6 emptyTextView.setOnTouchListener(touchListener);
173  6 albumArtImageView.setOnTouchListener(touchListener);
174   
175  6 albumArtImageView.setOnClickListener(new View.OnClickListener() {
 
176  2 toggle @Override
177    public void onClick(View view) {
178  2 toggleFullscreenAlbumArt();
179    }
180    });
181   
182  6 previousButton.setOnClickListener(new View.OnClickListener() {
 
183  2 toggle @Override
184    public void onClick(View view) {
185  2 warnIfNetworkOrStorageUnavailable();
186  2 getDownloadService().previous();
187  2 onCurrentChanged();
188  2 onProgressChanged();
189    }
190    });
191   
192  6 nextButton.setOnClickListener(new View.OnClickListener() {
 
193  7 toggle @Override
194    public void onClick(View view) {
195  7 warnIfNetworkOrStorageUnavailable();
196  7 if (getDownloadService().getCurrentPlayingIndex() < getDownloadService().size() - 1) {
197  7 getDownloadService().next();
198  7 onCurrentChanged();
199  7 onProgressChanged();
200    }
201    }
202    });
203   
204  6 pauseButton.setOnClickListener(new View.OnClickListener() {
 
205  6 toggle @Override
206    public void onClick(View view) {
207  6 getDownloadService().pause();
208  6 onCurrentChanged();
209  6 onProgressChanged();
210    }
211    });
212   
213  6 stopButton.setOnClickListener(new View.OnClickListener() {
 
214  2 toggle @Override
215    public void onClick(View view) {
216  2 getDownloadService().reset();
217  2 onCurrentChanged();
218  2 onProgressChanged();
219    }
220    });
221   
222  6 startButton.setOnClickListener(new View.OnClickListener() {
 
223  8 toggle @Override
224    public void onClick(View view) {
225  8 warnIfNetworkOrStorageUnavailable();
226  8 start();
227  8 onCurrentChanged();
228  8 onProgressChanged();
229    }
230    });
231   
232  6 shuffleButton.setOnClickListener(new View.OnClickListener() {
 
233  1 toggle @Override
234    public void onClick(View view) {
235  1 getDownloadService().shuffle();
236  1 Util.toast(DownloadActivity.this, R.string.download_menu_shuffle_notification);
237    }
238    });
239   
240    // Button: menu
241  6 ImageButton actionMenuButton = (ImageButton)findViewById(R.id.action_button_3);
242  6 actionMenuButton.setImageResource(R.drawable.ic_menu_moreoverflow);
243  6 actionMenuButton.setOnClickListener(new View.OnClickListener() {
 
244  7 toggle @Override
245    public void onClick(View view) {
246  7 openOptionsMenu();
247    }
248    });
249   
250  6 repeatButton.setOnClickListener(new View.OnClickListener() {
 
251  5 toggle @Override
252    public void onClick(View view) {
253  5 RepeatMode repeatMode = getDownloadService().getRepeatMode().next();
254  5 getDownloadService().setRepeatMode(repeatMode);
255  5 onDownloadListChanged();
256  5 switch (repeatMode) {
257  1 case OFF:
258  1 Util.toast(DownloadActivity.this, R.string.download_repeat_off);
259  1 break;
260  2 case ALL:
261  2 Util.toast(DownloadActivity.this, R.string.download_repeat_all);
262  2 break;
263  2 case SINGLE:
264  2 Util.toast(DownloadActivity.this, R.string.download_repeat_single);
265  2 break;
266  0 default:
267  0 break;
268    }
269    }
270    });
271   
272  6 equalizerButton.setOnClickListener(new View.OnClickListener() {
 
273  2 toggle @Override
274    public void onClick(View view) {
275  2 startActivity(new Intent(DownloadActivity.this, EqualizerActivity.class));
276    }
277    });
278   
279  6 visualizerButton.setOnClickListener(new View.OnClickListener() {
 
280  4 toggle @Override
281    public void onClick(View view) {
282  4 boolean active = !visualizerView.isActive();
283  4 visualizerView.setActive(active);
284  4 getDownloadService().setShowVisualization(visualizerView.isActive());
285  4 updateButtons();
286  4 Util.toast(DownloadActivity.this, active ? R.string.download_visualizer_on : R.string.download_visualizer_off);
287    }
288    });
289   
290  6 jukeboxButton.setOnClickListener(new View.OnClickListener() {
 
291  3 toggle @Override
292    public void onClick(View view) {
293  3 boolean jukeboxEnabled = !getDownloadService().isJukeboxEnabled();
294  3 getDownloadService().setJukeboxEnabled(jukeboxEnabled);
295  3 updateButtons();
296  3 Util.toast(DownloadActivity.this, jukeboxEnabled ? R.string.download_jukebox_on : R.string.download_jukebox_off, false);
297    }
298    });
299   
300  6 toggleListButton.setOnClickListener(new View.OnClickListener() {
 
301  5 toggle @Override
302    public void onClick(View view) {
303  5 toggleFullscreenAlbumArt();
304    }
305    });
306   
307  6 progressBar.setOnSliderChangeListener(new HorizontalSlider.OnSliderChangeListener() {
 
308  60 toggle @Override
309    public void onSliderChanged(View view, int position, boolean inProgress) {
310  60 Util.toast(DownloadActivity.this, Util.formatDuration(position / 1000), true);
311  60 if (!inProgress) {
312  4 getDownloadService().seekTo(position);
313  4 onProgressChanged();
314    }
315    }
316    });
317  6 playlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
 
318  3 toggle @Override
319    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
320  3 warnIfNetworkOrStorageUnavailable();
321  3 getDownloadService().play(position);
322  3 onCurrentChanged();
323  3 onProgressChanged();
324    }
325    });
326   
327  6 registerForContextMenu(playlistView);
328   
329  6 DownloadService downloadService = getDownloadService();
330  6 if (downloadService != null && getIntent().getBooleanExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE, false)) {
331  3 warnIfNetworkOrStorageUnavailable();
332  3 downloadService.setShufflePlayEnabled(true);
333    }
334   
335  6 boolean visualizerAvailable = downloadService != null && downloadService.getVisualizerController() != null;
336  6 boolean equalizerAvailable = downloadService != null && downloadService.getEqualizerController() != null;
337   
338  6 if (!equalizerAvailable) {
339  0 equalizerButton.setVisibility(View.GONE);
340    }
341  6 if (!visualizerAvailable) {
342  0 visualizerButton.setVisibility(View.GONE);
343    } else {
344  6 visualizerView = new VisualizerView(this);
345  6 visualizerViewLayout.addView(visualizerView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
346   
347  6 visualizerView.setOnTouchListener(new View.OnTouchListener() {
 
348  0 toggle @Override
349    public boolean onTouch(View view, MotionEvent motionEvent) {
350  0 visualizerView.setActive(!visualizerView.isActive());
351  0 getDownloadService().setShowVisualization(visualizerView.isActive());
352  0 updateButtons();
353  0 return true;
354    }
355    });
356    }
357   
358    // TODO: Extract to utility method and cache.
359  6 Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Regular.ttf");
360  6 equalizerButton.setTypeface(typeface);
361  6 visualizerButton.setTypeface(typeface);
362  6 jukeboxButton.setTypeface(typeface);
363    }
364   
 
365  12 toggle @Override
366    protected void onResume() {
367  12 super.onResume();
368   
369  12 final Handler handler = new Handler();
370  12 Runnable runnable = new Runnable() {
 
371  161 toggle @Override
372    public void run() {
373  161 handler.post(new Runnable() {
 
374  161 toggle @Override
375    public void run() {
376  161 update();
377    }
378    });
379    }
380    };
381   
382  12 executorService = Executors.newSingleThreadScheduledExecutor();
383  12 executorService.scheduleWithFixedDelay(runnable, 0L, 1000L, TimeUnit.MILLISECONDS);
384   
385  12 DownloadService downloadService = getDownloadService();
386  12 if (downloadService == null || downloadService.getCurrentPlaying() == null) {
387  0 playlistFlipper.setDisplayedChild(1);
388  0 buttonBarFlipper.setDisplayedChild(1);
389    }
390   
391  12 onDownloadListChanged();
392  12 onCurrentChanged();
393  12 onProgressChanged();
394  12 scrollToCurrent();
395  12 if (downloadService != null && downloadService.getKeepScreenOn()) {
396  11 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
397    } else {
398  1 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
399    }
400   
401  12 if (visualizerView != null) {
402  12 visualizerView.setActive(downloadService != null && downloadService.getShowVisualization());
403    }
404   
405  12 updateButtons();
406    }
407   
 
408  19 toggle private void updateButtons() {
409  19 boolean eqEnabled = getDownloadService() != null && getDownloadService().getEqualizerController() != null &&
410    getDownloadService().getEqualizerController().isEnabled();
411  19 equalizerButton.setTextColor(eqEnabled ? COLOR_BUTTON_ENABLED : COLOR_BUTTON_DISABLED);
412   
413  19 if (visualizerView != null) {
414  19 visualizerButton.setTextColor(visualizerView.isActive() ? COLOR_BUTTON_ENABLED : COLOR_BUTTON_DISABLED);
415    }
416   
417  19 boolean jukeboxEnabled = getDownloadService() != null && getDownloadService().isJukeboxEnabled();
418  19 jukeboxButton.setTextColor(jukeboxEnabled ? COLOR_BUTTON_ENABLED : COLOR_BUTTON_DISABLED);
419    }
420   
421    // Scroll to current playing/downloading.
 
422  19 toggle private void scrollToCurrent() {
423  19 if (getDownloadService() == null) {
424  0 return;
425    }
426   
427  41 for (int i = 0; i < playlistView.getAdapter().getCount(); i++) {
428  40 if (currentPlaying == playlistView.getItemAtPosition(i)) {
429  18 playlistView.setSelectionFromTop(i, 40);
430  18 return;
431    }
432    }
433  1 DownloadFile currentDownloading = getDownloadService().getCurrentDownloading();
434  1 for (int i = 0; i < playlistView.getAdapter().getCount(); i++) {
435  0 if (currentDownloading == playlistView.getItemAtPosition(i)) {
436  0 playlistView.setSelectionFromTop(i, 40);
437  0 return;
438    }
439    }
440    }
441   
 
442  12 toggle @Override
443    protected void onPause() {
444  12 super.onPause();
445  12 executorService.shutdown();
446  12 if (visualizerView != null) {
447  12 visualizerView.setActive(false);
448    }
449    }
450   
 
451  2 toggle @Override
452    protected Dialog onCreateDialog(int id) {
453  2 if (id == DIALOG_SAVE_PLAYLIST) {
454  2 AlertDialog.Builder builder;
455   
456  2 LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
457  2 final View layout = inflater.inflate(R.layout.save_playlist, (ViewGroup) findViewById(R.id.save_playlist_root));
458  2 playlistNameView = (EditText) layout.findViewById(R.id.save_playlist_name);
459   
460  2 builder = new AlertDialog.Builder(this);
461  2 builder.setTitle(R.string.download_playlist_title);
462  2 builder.setMessage(R.string.download_playlist_name);
463  2 builder.setPositiveButton(R.string.common_save, new DialogInterface.OnClickListener() {
 
464  1 toggle @Override
465    public void onClick(DialogInterface dialog, int id) {
466  1 savePlaylistInBackground(String.valueOf(playlistNameView.getText()));
467    }
468    });
469  2 builder.setNegativeButton(R.string.common_cancel, new DialogInterface.OnClickListener() {
 
470  1 toggle @Override
471    public void onClick(DialogInterface dialog, int id) {
472  1 dialog.cancel();
473    }
474    });
475  2 builder.setView(layout);
476  2 builder.setCancelable(true);
477   
478  2 return builder.create();
479    } else {
480  0 return super.onCreateDialog(id);
481    }
482    }
483   
 
484  2 toggle @Override
485    protected void onPrepareDialog(int id, Dialog dialog) {
486  2 if (id == DIALOG_SAVE_PLAYLIST) {
487  2 String playlistName = getDownloadService().getSuggestedPlaylistName();
488  2 if (playlistName != null) {
489  1 playlistNameView.setText(playlistName);
490    } else {
491  1 DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
492  1 playlistNameView.setText(dateFormat.format(new Date()));
493    }
494    }
495    }
496   
 
497  2 toggle @Override
498    public boolean onCreateOptionsMenu(Menu menu) {
499  2 MenuInflater inflater = getMenuInflater();
500  2 inflater.inflate(R.menu.nowplaying, menu);
501  2 return true;
502    }
503   
 
504  7 toggle @Override
505    public boolean onPrepareOptionsMenu(Menu menu) {
506  7 MenuItem savePlaylist = menu.findItem(R.id.menu_save_playlist);
507  7 boolean savePlaylistEnabled = !Util.isOffline(this);
508  7 savePlaylist.setEnabled(savePlaylistEnabled);
509  7 savePlaylist.setVisible(savePlaylistEnabled);
510  7 MenuItem screenOption = menu.findItem(R.id.menu_screen_on_off);
511  7 if (getDownloadService().getKeepScreenOn()) {
512  2 screenOption.setTitle(R.string.download_menu_screen_off);
513    } else {
514  5 screenOption.setTitle(R.string.download_menu_screen_on);
515    }
516  7 return super.onPrepareOptionsMenu(menu);
517    }
518   
 
519  4 toggle @Override
520    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
521  4 super.onCreateContextMenu(menu, view, menuInfo);
522  4 if (view == playlistView) {
523  4 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
524  4 DownloadFile downloadFile = (DownloadFile) playlistView.getItemAtPosition(info.position);
525   
526  4 MenuInflater inflater = getMenuInflater();
527  4 inflater.inflate(R.menu.nowplaying_context, menu);
528   
529  4 if (downloadFile.getSong().getParent() == null) {
530  0 menu.findItem(R.id.menu_show_album).setVisible(false);
531    }
532  4 if (Util.isOffline(this)) {
533  0 menu.findItem(R.id.menu_lyrics).setVisible(false);
534  0 menu.findItem(R.id.menu_save_playlist).setVisible(false);
535    }
536    }
537    }
538   
 
539  4 toggle @Override
540    public boolean onContextItemSelected(MenuItem menuItem) {
541  4 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo();
542  4 DownloadFile downloadFile = (DownloadFile) playlistView.getItemAtPosition(info.position);
543  4 return menuItemSelected(menuItem.getItemId(), downloadFile) || super.onContextItemSelected(menuItem);
544    }
545   
 
546  5 toggle @Override
547    public boolean onOptionsItemSelected(MenuItem menuItem) {
548  5 return menuItemSelected(menuItem.getItemId(), null) || super.onOptionsItemSelected(menuItem);
549    }
550   
 
551  9 toggle private boolean menuItemSelected(int menuItemId, DownloadFile song) {
552  9 switch (menuItemId) {
553  1 case R.id.menu_show_album:
554  1 Intent intent = new Intent(this, SelectAlbumActivity.class);
555  1 intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, song.getSong().getParent());
556  1 intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, song.getSong().getAlbum());
557  1 Util.startActivityWithoutTransition(this, intent);
558  1 return true;
559  1 case R.id.menu_lyrics:
560  1 intent = new Intent(this, LyricsActivity.class);
561  1 intent.putExtra(Constants.INTENT_EXTRA_NAME_ARTIST, song.getSong().getArtist());
562  1 intent.putExtra(Constants.INTENT_EXTRA_NAME_TITLE, song.getSong().getTitle());
563  1 Util.startActivityWithoutTransition(this, intent);
564  1 return true;
565  0 case R.id.menu_remove:
566  0 getDownloadService().remove(song);
567  0 onDownloadListChanged();
568  0 return true;
569  2 case R.id.menu_remove_all:
570  2 getDownloadService().setShufflePlayEnabled(false);
571  2 getDownloadService().clear();
572  2 onDownloadListChanged();
573  2 return true;
574  1 case R.id.menu_screen_on_off:
575  1 if (getDownloadService().getKeepScreenOn()) {
576  0 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
577  0 getDownloadService().setKeepScreenOn(false);
578    } else {
579  1 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
580  1 getDownloadService().setKeepScreenOn(true);
581    }
582  1 return true;
583  0 case R.id.menu_shuffle:
584  0 getDownloadService().shuffle();
585  0 Util.toast(this, R.string.download_menu_shuffle_notification);
586  0 return true;
587  2 case R.id.menu_save_playlist:
588  2 showDialog(DIALOG_SAVE_PLAYLIST);
589  2 return true;
590  2 default:
591  2 return false;
592    }
593    }
594   
 
595  161 toggle private void update() {
596  161 if (getDownloadService() == null) {
597  0 return;
598    }
599   
600  161 if (currentRevision != getDownloadService().getDownloadListUpdateRevision()) {
601  3 onDownloadListChanged();
602    }
603   
604  161 if (currentPlaying != getDownloadService().getCurrentPlaying()) {
605  2 onCurrentChanged();
606    }
607   
608  161 onProgressChanged();
609    }
610   
 
611  1 toggle private void savePlaylistInBackground(final String playlistName) {
612  1 Util.toast(DownloadActivity.this, getResources().getString(R.string.download_playlist_saving, playlistName));
613  1 getDownloadService().setSuggestedPlaylistName(playlistName);
614  1 new SilentBackgroundTask<Void>(this) {
 
615  1 toggle @Override
616    protected Void doInBackground() throws Throwable {
617  1 List<MusicDirectory.Entry> entries = new LinkedList<MusicDirectory.Entry>();
618  1 for (DownloadFile downloadFile : getDownloadService().getDownloads()) {
619  8 entries.add(downloadFile.getSong());
620    }
621  1 MusicService musicService = MusicServiceFactory.getMusicService(DownloadActivity.this);
622  1 musicService.createPlaylist(null, playlistName, entries, DownloadActivity.this, null);
623  1 return null;
624    }
625   
 
626  1 toggle @Override
627    protected void done(Void result) {
628  1 Util.toast(DownloadActivity.this, R.string.download_playlist_done);
629    }
630   
 
631  0 toggle @Override
632    protected void error(Throwable error) {
633  0 String msg = getResources().getString(R.string.download_playlist_error) + " " + getErrorMessage(error);
634  0 Util.toast(DownloadActivity.this, msg);
635    }
636    }.execute();
637    }
638   
 
639  7 toggle private void toggleFullscreenAlbumArt() {
640  7 scrollToCurrent();
641  7 if (playlistFlipper.getDisplayedChild() == 1) {
642  1 playlistFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_down_in));
643  1 playlistFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_down_out));
644  1 playlistFlipper.setDisplayedChild(0);
645  1 buttonBarFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_down_in));
646  1 buttonBarFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_down_out));
647  1 buttonBarFlipper.setDisplayedChild(0);
648   
649   
650    } else {
651  6 playlistFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_in));
652  6 playlistFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_out));
653  6 playlistFlipper.setDisplayedChild(1);
654  6 buttonBarFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_in));
655  6 buttonBarFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_up_out));
656  6 buttonBarFlipper.setDisplayedChild(1);
657    }
658    }
659   
 
660  8 toggle private void start() {
661  8 DownloadService service = getDownloadService();
662  8 PlayerState state = service.getPlayerState();
663  8 if (state == PAUSED || state == COMPLETED) {
664  3 service.start();
665  5 } else if (state == STOPPED || state == IDLE) {
666  5 warnIfNetworkOrStorageUnavailable();
667  5 int current = service.getCurrentPlayingIndex();
668    // TODO: Use play() method.
669  5 if (current == -1) {
670  4 service.play(0);
671    } else {
672  1 service.play(current);
673    }
674    }
675    }
676   
 
677  22 toggle private void onDownloadListChanged() {
678  22 DownloadService downloadService = getDownloadService();
679  22 if (downloadService == null) {
680  0 return;
681    }
682   
683  22 List<DownloadFile> list = downloadService.getDownloads();
684   
685  22 playlistView.setAdapter(new SongListAdapter(list));
686  22 emptyTextView.setVisibility(list.isEmpty() ? View.VISIBLE : View.GONE);
687  22 currentRevision = downloadService.getDownloadListUpdateRevision();
688   
689  22 switch (downloadService.getRepeatMode()) {
690  3 case OFF:
691  3 repeatButton.setImageResource(R.drawable.media_repeat_off);
692  3 break;
693  13 case ALL:
694  13 repeatButton.setImageResource(R.drawable.media_repeat_all);
695  13 break;
696  6 case SINGLE:
697  6 repeatButton.setImageResource(R.drawable.media_repeat_single);
698  6 break;
699  0 default:
700  0 break;
701    }
702    }
703   
 
704  48 toggle private void onCurrentChanged() {
705  48 if (getDownloadService() == null) {
706  0 return;
707    }
708   
709  48 currentPlaying = getDownloadService().getCurrentPlaying();
710  48 if (currentPlaying != null) {
711  42 MusicDirectory.Entry song = currentPlaying.getSong();
712  42 songTitleTextView.setText(song.getTitle());
713  42 albumTextView.setText(song.getAlbum());
714  42 artistTextView.setText(song.getArtist());
715  42 getImageLoader().loadImage(albumArtImageView, song, true, true);
716    } else {
717  6 songTitleTextView.setText(null);
718  6 albumTextView.setText(null);
719  6 artistTextView.setText(null);
720  6 getImageLoader().loadImage(albumArtImageView, null, true, false);
721    }
722    }
723   
 
724  216 toggle private void onProgressChanged() {
725  216 if (getDownloadService() == null) {
726  0 return;
727    }
728   
729  216 if (currentPlaying != null) {
730   
731  202 int millisPlayed = Math.max(0, getDownloadService().getPlayerPosition());
732  202 Integer duration = getDownloadService().getPlayerDuration();
733  202 int millisTotal = duration == null ? 0 : duration;
734   
735  202 positionTextView.setText(Util.formatDuration(millisPlayed / 1000));
736  202 durationTextView.setText(Util.formatDuration(millisTotal / 1000));
737  202 progressBar.setMax(millisTotal == 0 ? 100 : millisTotal); // Work-around for apparent bug.
738  202 progressBar.setProgress(millisPlayed);
739  202 progressBar.setSlidingEnabled(currentPlaying.isCompleteFileAvailable() || getDownloadService().isJukeboxEnabled());
740    } else {
741  14 positionTextView.setText("0:00");
742  14 durationTextView.setText("-:--");
743  14 progressBar.setProgress(0);
744  14 progressBar.setSlidingEnabled(false);
745    }
746   
747  216 PlayerState playerState = getDownloadService().getPlayerState();
748   
749  216 switch (playerState) {
750  38 case DOWNLOADING:
751  38 long bytes = currentPlaying.getPartialFile().length();
752  38 statusTextView.setText(getResources().getString(R.string.download_playerstate_downloading, Util.formatLocalizedBytes(bytes, this)));
753  38 break;
754  0 case PREPARING:
755  0 statusTextView.setText(R.string.download_playerstate_buffering);
756  0 break;
757  99 case STARTED:
758  99 if (getDownloadService().isShufflePlayEnabled()) {
759  55 statusTextView.setText(R.string.download_playerstate_playing_shuffle);
760    } else {
761  44 statusTextView.setText(null);
762    }
763  99 break;
764  79 default:
765  79 statusTextView.setText(null);
766  79 break;
767    }
768   
769  216 switch (playerState) {
770  99 case STARTED:
771  99 pauseButton.setVisibility(View.VISIBLE);
772  99 stopButton.setVisibility(View.GONE);
773  99 startButton.setVisibility(View.GONE);
774  99 break;
775  38 case DOWNLOADING:
776  0 case PREPARING:
777  38 pauseButton.setVisibility(View.GONE);
778  38 stopButton.setVisibility(View.VISIBLE);
779  38 startButton.setVisibility(View.GONE);
780  38 break;
781  79 default:
782  79 pauseButton.setVisibility(View.GONE);
783  79 stopButton.setVisibility(View.GONE);
784  79 startButton.setVisibility(View.VISIBLE);
785  79 break;
786    }
787   
788  216 jukeboxButton.setTextColor(getDownloadService().isJukeboxEnabled() ? COLOR_BUTTON_ENABLED : COLOR_BUTTON_DISABLED);
789    }
790   
 
791    private class SongListAdapter extends ArrayAdapter<DownloadFile> {
 
792  22 toggle public SongListAdapter(List<DownloadFile> entries) {
793  22 super(DownloadActivity.this, android.R.layout.simple_list_item_1, entries);
794    }
795   
 
796  106 toggle @Override
797    public View getView(int position, View convertView, ViewGroup parent) {
798  106 SongView view;
799  106 if (convertView != null && convertView instanceof SongView) {
800  31 view = (SongView) convertView;
801    } else {
802  75 view = new SongView(DownloadActivity.this);
803    }
804  106 DownloadFile downloadFile = getItem(position);
805  106 view.setSong(downloadFile.getSong(), false);
806  106 return view;
807    }
808    }
809   
 
810  92 toggle @Override
811    public boolean onTouchEvent(MotionEvent me) {
812  92 return gestureScanner.onTouchEvent(me);
813    }
814   
 
815  56 toggle @Override
816    public boolean onDown(MotionEvent me) {
817  56 return false;
818    }
819   
 
820  13 toggle @Override
821    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
822   
823  13 DownloadService downloadService = getDownloadService();
824  13 if (downloadService == null) {
825  0 return false;
826    }
827   
828    // Right to Left swipe
829  13 if (e1.getX() - e2.getX() > swipeDistance && Math.abs(velocityX) > swipeVelocity) {
830  3 warnIfNetworkOrStorageUnavailable();
831  3 if (downloadService.getCurrentPlayingIndex() < downloadService.size() - 1) {
832  3 downloadService.next();
833  3 onCurrentChanged();
834  3 onProgressChanged();
835    }
836  3 return true;
837    }
838   
839    // Left to Right swipe
840  10 if (e2.getX() - e1.getX() > swipeDistance && Math.abs(velocityX) > swipeVelocity) {
841  3 warnIfNetworkOrStorageUnavailable();
842  3 downloadService.previous();
843  3 onCurrentChanged();
844  3 onProgressChanged();
845  3 return true;
846    }
847   
848    // Top to Bottom swipe
849  7 if (e2.getY() - e1.getY() > swipeDistance && Math.abs(velocityY) > swipeVelocity) {
850  3 warnIfNetworkOrStorageUnavailable();
851  3 downloadService.seekTo(downloadService.getPlayerPosition() + 30000);
852  3 onProgressChanged();
853  3 return true;
854    }
855   
856    // Bottom to Top swipe
857  4 if (e1.getY() - e2.getY() > swipeDistance && Math.abs(velocityY) > swipeVelocity) {
858  2 warnIfNetworkOrStorageUnavailable();
859  2 downloadService.seekTo(downloadService.getPlayerPosition() - 8000);
860  2 onProgressChanged();
861  2 return true;
862    }
863   
864  2 return false;
865    }
866   
 
867  0 toggle @Override
868    public void onLongPress(MotionEvent e) {
869    }
870   
 
871  95 toggle @Override
872    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
873  95 return false;
874    }
875   
 
876  0 toggle @Override
877    public void onShowPress(MotionEvent e) {
878    }
879   
 
880  39 toggle @Override
881    public boolean onSingleTapUp(MotionEvent e) {
882  39 return false;
883    }
884    }