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
61   178   26   6,78
24   129   0,43   9
9     2,89  
1    
This report was generated with an evaluation server license. Purchase Clover or configure your license.
 
  SongView       Line # 44 61 26 87,2% 0.87234044
 
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.util;
20   
21    import android.content.Context;
22    import android.os.Handler;
23    import android.util.Log;
24    import android.view.LayoutInflater;
25    import android.view.View;
26    import android.widget.Checkable;
27    import android.widget.CheckedTextView;
28    import android.widget.LinearLayout;
29    import android.widget.TextView;
30    import net.sourceforge.subsonic.androidapp.R;
31    import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
32    import net.sourceforge.subsonic.androidapp.service.DownloadService;
33    import net.sourceforge.subsonic.androidapp.service.DownloadServiceImpl;
34    import net.sourceforge.subsonic.androidapp.service.DownloadFile;
35   
36    import java.io.File;
37    import java.util.WeakHashMap;
38   
39    /**
40    * Used to display songs in a {@code ListView}.
41    *
42    * @author Sindre Mehus
43    */
 
44    public class SongView extends LinearLayout implements Checkable {
45   
46    private static final String TAG = SongView.class.getSimpleName();
47    private static final WeakHashMap<SongView, ?> INSTANCES = new WeakHashMap<SongView, Object>();
48    private static Handler handler;
49   
50    private CheckedTextView checkedTextView;
51    private TextView titleTextView;
52    private TextView artistTextView;
53    private TextView durationTextView;
54    private TextView statusTextView;
55    private MusicDirectory.Entry song;
56   
 
57  120 toggle public SongView(Context context) {
58  120 super(context);
59  120 LayoutInflater.from(context).inflate(R.layout.song_list_item, this, true);
60   
61  120 checkedTextView = (CheckedTextView) findViewById(R.id.song_check);
62  120 titleTextView = (TextView) findViewById(R.id.song_title);
63  120 artistTextView = (TextView) findViewById(R.id.song_artist);
64  120 durationTextView = (TextView) findViewById(R.id.song_duration);
65  120 statusTextView = (TextView) findViewById(R.id.song_status);
66   
67  120 INSTANCES.put(this, null);
68  120 int instanceCount = INSTANCES.size();
69  120 if (instanceCount > 50) {
70  0 Log.w(TAG, instanceCount + " live SongView instances");
71    }
72  120 startUpdater();
73    }
74   
 
75  233 toggle public void setSong(MusicDirectory.Entry song, boolean checkable) {
76  233 this.song = song;
77  233 StringBuilder artist = new StringBuilder(40);
78   
79  233 String bitRate = null;
80  233 if (song.getBitRate() != null) {
81  193 bitRate = String.format(getContext().getString(R.string.song_details_kbps), song.getBitRate());
82    }
83   
84  233 String fileFormat = null;
85  233 if (song.getTranscodedSuffix() != null && !song.getTranscodedSuffix().equals(song.getSuffix())) {
86  0 fileFormat = String.format("%s > %s", song.getSuffix(), song.getTranscodedSuffix());
87    } else {
88  233 fileFormat = song.getSuffix();
89    }
90   
91  233 artist.append(song.getArtist()).append(" (")
92  233 .append(String.format(getContext().getString(R.string.song_details_all), bitRate == null ? "" : bitRate, fileFormat))
93    .append(")");
94   
95  233 titleTextView.setText(song.getTitle());
96  233 artistTextView.setText(artist);
97  233 durationTextView.setText(Util.formatDuration(song.getDuration()));
98  233 checkedTextView.setVisibility(checkable && !song.isVideo() ? View.VISIBLE : View.GONE);
99   
100  233 update();
101    }
102   
 
103  1032 toggle private void update() {
104  1032 DownloadService downloadService = DownloadServiceImpl.getInstance();
105  1032 if (downloadService == null) {
106  0 return;
107    }
108   
109  1032 DownloadFile downloadFile = downloadService.forSong(song);
110  1032 File completeFile = downloadFile.getCompleteFile();
111  1032 File partialFile = downloadFile.getPartialFile();
112   
113  1032 int leftImage = 0;
114  1032 int rightImage = 0;
115   
116  1032 if (completeFile.exists()) {
117  273 leftImage = downloadFile.isSaved() ? R.drawable.ic_stat_saved : R.drawable.ic_stat_downloaded;
118    }
119   
120  1032 if (downloadFile.isDownloading() && !downloadFile.isDownloadCancelled() && partialFile.exists()) {
121  51 statusTextView.setText(Util.formatLocalizedBytes(partialFile.length(), getContext()));
122  51 rightImage = R.drawable.ic_stat_downloading;
123    } else {
124  981 statusTextView.setText(null);
125    }
126  1032 statusTextView.setCompoundDrawablesWithIntrinsicBounds(leftImage, 0, rightImage, 0);
127   
128  1032 boolean playing = downloadService.getCurrentPlaying() == downloadFile;
129  1032 if (playing) {
130  98 titleTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_stat_play, 0, 0, 0);
131    } else {
132  934 titleTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
133    }
134    }
135   
 
136  120 toggle private static synchronized void startUpdater() {
137  120 if (handler != null) {
138  119 return;
139    }
140   
141  1 handler = new Handler();
142  1 Runnable runnable = new Runnable() {
 
143  446 toggle @Override
144    public void run() {
145  446 updateAll();
146  446 handler.postDelayed(this, 1000L);
147    }
148    };
149  1 handler.postDelayed(runnable, 1000L);
150    }
151   
 
152  446 toggle private static void updateAll() {
153  446 try {
154  446 for (SongView view : INSTANCES.keySet()) {
155  7614 if (view.isShown()) {
156  799 view.update();
157    }
158    }
159    } catch (Throwable x) {
160  0 Log.w(TAG, "Error when updating song views.", x);
161    }
162    }
163   
 
164  923 toggle @Override
165    public void setChecked(boolean b) {
166  923 checkedTextView.setChecked(b);
167    }
168   
 
169  0 toggle @Override
170    public boolean isChecked() {
171  0 return checkedTextView.isChecked();
172    }
173   
 
174  0 toggle @Override
175    public void toggle() {
176  0 checkedTextView.toggle();
177    }
178    }