Merge lp:~karni/ubuntuone-android-music/playlist-ux-and-sync into lp:ubuntuone-android-music/v2
- playlist-ux-and-sync
- Merge into v2
Proposed by
Michał Karnicki
Status: | Merged |
---|---|
Approved by: | Michał Karnicki |
Approved revision: | 32 |
Merged at revision: | 32 |
Proposed branch: | lp:~karni/ubuntuone-android-music/playlist-ux-and-sync |
Merge into: | lp:ubuntuone-android-music/v2 |
Prerequisite: | lp:~karni/ubuntuone-android-music/added-missing-dao |
Diff against target: |
1525 lines (+527/-267) 25 files modified
AndroidManifest.xml (+7/-0) res/layout/activity_playlist.xml (+0/-76) res/layout/activity_playlists.xml (+13/-0) res/values/ids.xml (+1/-0) res/values/strings.xml (+5/-0) src/com/ubuntuone/android/music/adapter/U1PlaylistAdapter.java (+7/-2) src/com/ubuntuone/android/music/model/Song.java (+1/-1) src/com/ubuntuone/android/music/provider/MusicContract.java (+11/-3) src/com/ubuntuone/android/music/provider/MusicDatabase.java (+1/-0) src/com/ubuntuone/android/music/provider/MusicProvider.java (+6/-6) src/com/ubuntuone/android/music/provider/MusicProviderUtils.java (+70/-3) src/com/ubuntuone/android/music/service/MusicService.java (+16/-5) src/com/ubuntuone/android/music/service/SyncService.java (+59/-10) src/com/ubuntuone/android/music/ui/AlbumsFragment.java (+8/-1) src/com/ubuntuone/android/music/ui/HomeActivity.java (+50/-4) src/com/ubuntuone/android/music/ui/PlayerFragment.java (+1/-1) src/com/ubuntuone/android/music/ui/PlaylistActivity.java (+0/-1) src/com/ubuntuone/android/music/ui/PlaylistsActivity.java (+148/-6) src/com/ubuntuone/android/music/ui/PlaylistsFragment.java (+33/-111) src/com/ubuntuone/android/music/ui/SongsFragment.java (+58/-18) src/com/ubuntuone/android/music/ui/dialog/InfoAlertDialog.java (+12/-6) test/src/com/ubuntuone/android/music/provider/MusicProviderInsertTest.java (+2/-2) test/src/com/ubuntuone/android/music/provider/MusicProviderQueryTest.java (+4/-4) test/src/com/ubuntuone/android/music/provider/MusicProviderUtilsTest.java (+10/-7) test/src/com/ubuntuone/android/music/ui/SongsPageTest.java (+4/-0) |
To merge this branch: | bzr merge lp:~karni/ubuntuone-android-music/playlist-ux-and-sync |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Roberto Alsina (community) | Approve | ||
Review via email: mp+136731@code.launchpad.net |
Commit message
Added playlist manipulation and sync.
Description of the change
This branch allows adding and removing items from playlists, as well as sync them with U1.
Create new playlist feature is pending minor rework after recent u1-server changes rolled out.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'AndroidManifest.xml' | |||
2 | --- AndroidManifest.xml 2012-11-08 14:14:54 +0000 | |||
3 | +++ AndroidManifest.xml 2012-11-28 17:49:20 +0000 | |||
4 | @@ -63,6 +63,11 @@ | |||
5 | 63 | android:theme="@style/Theme.Sherlock.Light" > | 63 | android:theme="@style/Theme.Sherlock.Light" > |
6 | 64 | </activity> | 64 | </activity> |
7 | 65 | <activity | 65 | <activity |
8 | 66 | android:name=".ui.PlaylistsActivity" | ||
9 | 67 | android:label="U1 Playlists" | ||
10 | 68 | android:theme="@style/Theme.Sherlock.Light.Dialog" > | ||
11 | 69 | </activity> | ||
12 | 70 | <activity | ||
13 | 66 | android:name=".ui.PlayerActivity" | 71 | android:name=".ui.PlayerActivity" |
14 | 67 | android:label="U1 Player" | 72 | android:label="U1 Player" |
15 | 68 | android:screenOrientation="portrait" > | 73 | android:screenOrientation="portrait" > |
16 | @@ -78,6 +83,7 @@ | |||
17 | 78 | android:exported="false" > | 83 | android:exported="false" > |
18 | 79 | <intent-filter> | 84 | <intent-filter> |
19 | 80 | <action android:name="com.ubuntuone.android.music.ACTION_SYNC_MUSIC_METADATA" /> | 85 | <action android:name="com.ubuntuone.android.music.ACTION_SYNC_MUSIC_METADATA" /> |
20 | 86 | <action android:name="com.ubuntuone.android.music.ACTION_SYNC_PLAYLISTS" /> | ||
21 | 81 | </intent-filter> | 87 | </intent-filter> |
22 | 82 | </service> | 88 | </service> |
23 | 83 | <service | 89 | <service |
24 | @@ -87,6 +93,7 @@ | |||
25 | 87 | 93 | ||
26 | 88 | <provider | 94 | <provider |
27 | 89 | android:name=".provider.MusicProvider" | 95 | android:name=".provider.MusicProvider" |
28 | 96 | android:exported="false" | ||
29 | 90 | android:authorities="com.ubuntuone.android.music" | 97 | android:authorities="com.ubuntuone.android.music" |
30 | 91 | android:label="@string/app_name" | 98 | android:label="@string/app_name" |
31 | 92 | android:syncable="true" | 99 | android:syncable="true" |
32 | 93 | 100 | ||
33 | === removed file 'res/layout/activity_playlist.xml' | |||
34 | --- res/layout/activity_playlist.xml 2012-09-19 23:50:20 +0000 | |||
35 | +++ res/layout/activity_playlist.xml 1970-01-01 00:00:00 +0000 | |||
36 | @@ -1,76 +0,0 @@ | |||
37 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
38 | 2 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
39 | 3 | xmlns:tools="http://schemas.android.com/tools" | ||
40 | 4 | android:layout_width="match_parent" | ||
41 | 5 | android:layout_height="match_parent" > | ||
42 | 6 | |||
43 | 7 | <ImageView | ||
44 | 8 | android:id="@+id/image" | ||
45 | 9 | android:layout_width="@dimen/header_image_size" | ||
46 | 10 | android:layout_height="@dimen/header_image_size" | ||
47 | 11 | android:layout_alignParentLeft="true" | ||
48 | 12 | android:layout_alignParentTop="true" | ||
49 | 13 | android:background="@drawable/ic_action_help" | ||
50 | 14 | android:minHeight="@dimen/header_image_size" | ||
51 | 15 | android:minWidth="@dimen/header_image_size" /> | ||
52 | 16 | |||
53 | 17 | <TextView | ||
54 | 18 | android:id="@+id/text1" | ||
55 | 19 | android:layout_width="match_parent" | ||
56 | 20 | android:layout_height="wrap_content" | ||
57 | 21 | android:layout_alignTop="@id/image" | ||
58 | 22 | android:layout_toRightOf="@id/image" | ||
59 | 23 | android:gravity="top|left" | ||
60 | 24 | android:paddingLeft="4dp" | ||
61 | 25 | android:paddingTop="4dp" | ||
62 | 26 | android:singleLine="true" | ||
63 | 27 | android:textStyle="bold" | ||
64 | 28 | android:textAppearance="@android:style/TextAppearance.Medium" | ||
65 | 29 | android:textColor="@android:color/primary_text_light" /> | ||
66 | 30 | |||
67 | 31 | <TextView | ||
68 | 32 | android:id="@+id/text2" | ||
69 | 33 | android:layout_width="match_parent" | ||
70 | 34 | android:layout_height="wrap_content" | ||
71 | 35 | android:layout_below="@id/text1" | ||
72 | 36 | android:layout_toRightOf="@id/image" | ||
73 | 37 | android:gravity="top|left" | ||
74 | 38 | android:paddingLeft="4dp" | ||
75 | 39 | android:singleLine="true" | ||
76 | 40 | android:textAppearance="@android:style/TextAppearance.Small" | ||
77 | 41 | android:textColor="@android:color/tertiary_text_light" /> | ||
78 | 42 | |||
79 | 43 | <LinearLayout | ||
80 | 44 | android:layout_width="match_parent" | ||
81 | 45 | android:layout_height="wrap_content" | ||
82 | 46 | android:layout_alignBottom="@id/image" | ||
83 | 47 | android:layout_toRightOf="@id/image" | ||
84 | 48 | android:weightSum="2" > | ||
85 | 49 | |||
86 | 50 | <Button | ||
87 | 51 | android:id="@+id/shuffle_all" | ||
88 | 52 | android:layout_width="0dp" | ||
89 | 53 | android:layout_height="wrap_content" | ||
90 | 54 | android:layout_weight="1" | ||
91 | 55 | android:text="@string/shuffle_all" | ||
92 | 56 | android:textAppearance="@android:style/TextAppearance.Small" | ||
93 | 57 | android:onClick="shuffleAll" /> | ||
94 | 58 | |||
95 | 59 | <Button | ||
96 | 60 | android:id="@+id/repeat_all" | ||
97 | 61 | android:layout_width="0dp" | ||
98 | 62 | android:layout_height="wrap_content" | ||
99 | 63 | android:layout_weight="1" | ||
100 | 64 | android:text="@string/repeat_all" | ||
101 | 65 | android:textAppearance="@android:style/TextAppearance.Small" | ||
102 | 66 | android:onClick="repeatAll" /> | ||
103 | 67 | </LinearLayout> | ||
104 | 68 | |||
105 | 69 | <FrameLayout | ||
106 | 70 | android:id="@+id/songs" | ||
107 | 71 | android:layout_width="match_parent" | ||
108 | 72 | android:layout_height="match_parent" | ||
109 | 73 | android:layout_below="@id/image" > | ||
110 | 74 | </FrameLayout> | ||
111 | 75 | |||
112 | 76 | </RelativeLayout> | ||
113 | 77 | \ No newline at end of file | 0 | \ No newline at end of file |
114 | 78 | 1 | ||
115 | === added file 'res/layout/activity_playlists.xml' | |||
116 | --- res/layout/activity_playlists.xml 1970-01-01 00:00:00 +0000 | |||
117 | +++ res/layout/activity_playlists.xml 2012-11-28 17:49:20 +0000 | |||
118 | @@ -0,0 +1,13 @@ | |||
119 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
120 | 2 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
121 | 3 | xmlns:tools="http://schemas.android.com/tools" | ||
122 | 4 | android:layout_width="match_parent" | ||
123 | 5 | android:layout_height="match_parent" > | ||
124 | 6 | |||
125 | 7 | <fragment | ||
126 | 8 | android:id="@+id/playlists" | ||
127 | 9 | android:name="com.ubuntuone.android.music.ui.PlaylistsFragment" | ||
128 | 10 | android:layout_width="match_parent" | ||
129 | 11 | android:layout_height="match_parent" /> | ||
130 | 12 | |||
131 | 13 | </RelativeLayout> | ||
132 | 0 | 14 | ||
133 | === modified file 'res/values/ids.xml' | |||
134 | --- res/values/ids.xml 2012-11-08 14:14:54 +0000 | |||
135 | +++ res/values/ids.xml 2012-11-28 17:49:20 +0000 | |||
136 | @@ -15,5 +15,6 @@ | |||
137 | 15 | <item type="id" name="context_play" /> | 15 | <item type="id" name="context_play" /> |
138 | 16 | <item type="id" name="context_star" /> | 16 | <item type="id" name="context_star" /> |
139 | 17 | <item type="id" name="context_add_to_playlist" /> | 17 | <item type="id" name="context_add_to_playlist" /> |
140 | 18 | <item type="id" name="context_remove_from_playlist" /> | ||
141 | 18 | <item type="id" name="context_add_to_queue" /> | 19 | <item type="id" name="context_add_to_queue" /> |
142 | 19 | </resources> | 20 | </resources> |
143 | 20 | \ No newline at end of file | 21 | \ No newline at end of file |
144 | 21 | 22 | ||
145 | === modified file 'res/values/strings.xml' | |||
146 | --- res/values/strings.xml 2012-11-08 14:14:54 +0000 | |||
147 | +++ res/values/strings.xml 2012-11-28 17:49:20 +0000 | |||
148 | @@ -31,7 +31,11 @@ | |||
149 | 31 | <string name="playlist_stats">%1$s songs</string> | 31 | <string name="playlist_stats">%1$s songs</string> |
150 | 32 | <string name="playlist_title">Playlist title</string> | 32 | <string name="playlist_title">Playlist title</string> |
151 | 33 | <string name="creating_playlist">Creating playlist…</string> | 33 | <string name="creating_playlist">Creating playlist…</string> |
152 | 34 | <string name="add_to">Add to…</string> | ||
153 | 35 | <string name="added_to_fmt">Added to %s.</string> | ||
154 | 36 | <string name="sync_pending">Sync pending</string> | ||
155 | 34 | <string name="creating_playlist_failed_title">Cound\'t create playlist</string> | 37 | <string name="creating_playlist_failed_title">Cound\'t create playlist</string> |
156 | 38 | <string name="updating_playlist_failed_title">Cound\'t update playlist</string> | ||
157 | 35 | 39 | ||
158 | 36 | <string name="genres_title">genres</string> | 40 | <string name="genres_title">genres</string> |
159 | 37 | <string name="genres_loading">Getting genres…</string> | 41 | <string name="genres_loading">Getting genres…</string> |
160 | @@ -56,6 +60,7 @@ | |||
161 | 56 | <string name="description_play">Play</string> | 60 | <string name="description_play">Play</string> |
162 | 57 | <string name="description_star">Star</string> | 61 | <string name="description_star">Star</string> |
163 | 58 | <string name="description_add_to_playlist">Add to playlist</string> | 62 | <string name="description_add_to_playlist">Add to playlist</string> |
164 | 63 | <string name="description_remove_from_playlist">Remove from playlist</string> | ||
165 | 59 | <string name="description_add_to_queue">Add to queue</string> | 64 | <string name="description_add_to_queue">Add to queue</string> |
166 | 60 | 65 | ||
167 | 61 | <string name="shuffle_all">Shuffle all</string> | 66 | <string name="shuffle_all">Shuffle all</string> |
168 | 62 | 67 | ||
169 | === modified file 'src/com/ubuntuone/android/music/adapter/U1PlaylistAdapter.java' | |||
170 | --- src/com/ubuntuone/android/music/adapter/U1PlaylistAdapter.java 2012-11-22 10:23:21 +0000 | |||
171 | +++ src/com/ubuntuone/android/music/adapter/U1PlaylistAdapter.java 2012-11-28 17:49:20 +0000 | |||
172 | @@ -157,8 +157,13 @@ | |||
173 | 157 | 157 | ||
174 | 158 | String name = cursor.getString(cursor.getColumnIndex(Playlists.PLAYLIST_NAME)); | 158 | String name = cursor.getString(cursor.getColumnIndex(Playlists.PLAYLIST_NAME)); |
175 | 159 | int length = cursor.getInt(cursor.getColumnIndex(Playlists.PLAYLIST_SONG_COUNT)); | 159 | int length = cursor.getInt(cursor.getColumnIndex(Playlists.PLAYLIST_SONG_COUNT)); |
178 | 160 | 160 | int dirty = cursor.getInt(cursor.getColumnIndex(Playlists.DIRTY)); | |
179 | 161 | holder.playlistTitle.setText(name); | 161 | if (dirty != 0) { |
180 | 162 | holder.playlistTitle.setText(String.format("%s [%s]", | ||
181 | 163 | name, context.getString(R.string.sync_pending))); | ||
182 | 164 | } else { | ||
183 | 165 | holder.playlistTitle.setText(name); | ||
184 | 166 | } | ||
185 | 162 | // TODO Get plural string resource for item(s). | 167 | // TODO Get plural string resource for item(s). |
186 | 163 | if (length == 0) { | 168 | if (length == 0) { |
187 | 164 | holder.playlistSongCount.setText(String.format("No songs", length)); | 169 | holder.playlistSongCount.setText(String.format("No songs", length)); |
188 | 165 | 170 | ||
189 | === modified file 'src/com/ubuntuone/android/music/model/Song.java' | |||
190 | --- src/com/ubuntuone/android/music/model/Song.java 2012-11-08 14:14:54 +0000 | |||
191 | +++ src/com/ubuntuone/android/music/model/Song.java 2012-11-28 17:49:20 +0000 | |||
192 | @@ -69,7 +69,7 @@ | |||
193 | 69 | 69 | ||
194 | 70 | public Song(Context context, Uri uri) { | 70 | public Song(Context context, Uri uri) { |
195 | 71 | ContentResolver resolver = context.getContentResolver(); | 71 | ContentResolver resolver = context.getContentResolver(); |
197 | 72 | String[] projection = Songs.DEFAULT_PROJECTION; | 72 | String[] projection = Songs.getDefaultProjection(); |
198 | 73 | Cursor cursor = null; | 73 | Cursor cursor = null; |
199 | 74 | try { | 74 | try { |
200 | 75 | cursor = resolver.query(uri, projection, null, null, null); | 75 | cursor = resolver.query(uri, projection, null, null, null); |
201 | 76 | 76 | ||
202 | === modified file 'src/com/ubuntuone/android/music/provider/MusicContract.java' | |||
203 | --- src/com/ubuntuone/android/music/provider/MusicContract.java 2012-11-21 15:03:12 +0000 | |||
204 | +++ src/com/ubuntuone/android/music/provider/MusicContract.java 2012-11-28 17:49:20 +0000 | |||
205 | @@ -153,6 +153,8 @@ | |||
206 | 153 | String PLAYLIST_SONG_COUNT = "playlist_song_count"; | 153 | String PLAYLIST_SONG_COUNT = "playlist_song_count"; |
207 | 154 | /** Full URL to this playlist online. */ | 154 | /** Full URL to this playlist online. */ |
208 | 155 | String PLAYLIST_URL = "playlist_url"; | 155 | String PLAYLIST_URL = "playlist_url"; |
209 | 156 | /** Flag indicating playlist should be sync'ed up. */ | ||
210 | 157 | String DIRTY = "dirty"; | ||
211 | 156 | } | 158 | } |
212 | 157 | 159 | ||
213 | 158 | interface PlaylistSongsColumns extends SongsColumns | 160 | interface PlaylistSongsColumns extends SongsColumns |
214 | @@ -376,7 +378,7 @@ | |||
215 | 376 | .buildUpon().appendPath(PATH_CACHED).build(); | 378 | .buildUpon().appendPath(PATH_CACHED).build(); |
216 | 377 | 379 | ||
217 | 378 | /** Default query projection. */ | 380 | /** Default query projection. */ |
219 | 379 | public static final String[] DEFAULT_PROJECTION = new String[] { | 381 | private static final String[] DEFAULT_PROJECTION = new String[] { |
220 | 380 | Songs._ID, Songs.SONG_ID, Songs.SONG_TITLE, Songs.SONG_ALBUM, | 382 | Songs._ID, Songs.SONG_ID, Songs.SONG_TITLE, Songs.SONG_ALBUM, |
221 | 381 | Songs.SONG_ALBUM_ID, Songs.SONG_ALBUM_ARTIST, | 383 | Songs.SONG_ALBUM_ID, Songs.SONG_ALBUM_ARTIST, |
222 | 382 | Songs.SONG_ARTIST, Songs.SONG_ARTIST_ID, Songs.SONG_GENRE, | 384 | Songs.SONG_ARTIST, Songs.SONG_ARTIST_ID, Songs.SONG_GENRE, |
223 | @@ -385,6 +387,12 @@ | |||
224 | 385 | Songs.SONG_BIT_RATE, Songs.SONG_SUFFIX, Songs.SONG_CONTENT_TYPE, | 387 | Songs.SONG_BIT_RATE, Songs.SONG_SUFFIX, Songs.SONG_CONTENT_TYPE, |
225 | 386 | Songs.SONG_PATH, Songs.SONG_LAST_PLAYED_AT, Songs.STARRED, Songs.SONG_IS_PLAYING, | 388 | Songs.SONG_PATH, Songs.SONG_LAST_PLAYED_AT, Songs.STARRED, Songs.SONG_IS_PLAYING, |
226 | 387 | }; | 389 | }; |
227 | 390 | |||
228 | 391 | public static String[] getDefaultProjection() { | ||
229 | 392 | // karni: Earn $10 and tell me why you have to return a COPY of a *static final* for it | ||
230 | 393 | // not to change here, in MusicContract#DEFAULT_PROJECTION. Platform bug? | ||
231 | 394 | return DEFAULT_PROJECTION.clone(); | ||
232 | 395 | } | ||
233 | 388 | 396 | ||
234 | 389 | /** Default "ORDER BY" clause. */ | 397 | /** Default "ORDER BY" clause. */ |
235 | 390 | public static final String DEFAULT_SORT = SongsColumns.SONG_TITLE | 398 | public static final String DEFAULT_SORT = SongsColumns.SONG_TITLE |
236 | @@ -435,7 +443,7 @@ | |||
237 | 435 | /** Default query projection. */ | 443 | /** Default query projection. */ |
238 | 436 | public static final String[] DEFAULT_PROJECTION = new String[] { | 444 | public static final String[] DEFAULT_PROJECTION = new String[] { |
239 | 437 | Playlists._ID, Playlists.PLAYLIST_ID, Playlists.PLAYLIST_NAME, | 445 | Playlists._ID, Playlists.PLAYLIST_ID, Playlists.PLAYLIST_NAME, |
241 | 438 | Playlists.PLAYLIST_SONG_COUNT, Playlists.STARRED | 446 | Playlists.PLAYLIST_SONG_COUNT, Playlists.STARRED, Playlists.DIRTY |
242 | 439 | }; | 447 | }; |
243 | 440 | 448 | ||
244 | 441 | public static final String[] SONGS_DEFAULT_PROJECTION = new String[] { | 449 | public static final String[] SONGS_DEFAULT_PROJECTION = new String[] { |
245 | @@ -503,7 +511,7 @@ | |||
246 | 503 | } | 511 | } |
247 | 504 | 512 | ||
248 | 505 | public static class PlaylistSongs implements PlaylistSongsColumns, SyncColumns, | 513 | public static class PlaylistSongs implements PlaylistSongsColumns, SyncColumns, |
250 | 506 | SongsColumns, BaseColumns | 514 | SongsColumns, StarredColumn, BaseColumns |
251 | 507 | { | 515 | { |
252 | 508 | public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon() | 516 | public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon() |
253 | 509 | .appendPath(PATH_PLAYLISTS_SONGS).build(); | 517 | .appendPath(PATH_PLAYLISTS_SONGS).build(); |
254 | 510 | 518 | ||
255 | === modified file 'src/com/ubuntuone/android/music/provider/MusicDatabase.java' | |||
256 | --- src/com/ubuntuone/android/music/provider/MusicDatabase.java 2012-11-21 15:03:12 +0000 | |||
257 | +++ src/com/ubuntuone/android/music/provider/MusicDatabase.java 2012-11-28 17:49:20 +0000 | |||
258 | @@ -202,6 +202,7 @@ | |||
259 | 202 | + PlaylistsColumns.PLAYLIST_NAME + " TEXT NOT NULL, " | 202 | + PlaylistsColumns.PLAYLIST_NAME + " TEXT NOT NULL, " |
260 | 203 | + PlaylistsColumns.PLAYLIST_SONG_COUNT + " INTEGER NOT NULL DEFAULT 0, " | 203 | + PlaylistsColumns.PLAYLIST_SONG_COUNT + " INTEGER NOT NULL DEFAULT 0, " |
261 | 204 | + PlaylistsColumns.PLAYLIST_URL + " TEXT NOT NULL, " | 204 | + PlaylistsColumns.PLAYLIST_URL + " TEXT NOT NULL, " |
262 | 205 | + PlaylistsColumns.DIRTY + " INTEGER NOT NULL DEFAULT 0, " | ||
263 | 205 | + "UNIQUE (" + PlaylistsColumns.PLAYLIST_ID + ") ON CONFLICT IGNORE)"); | 206 | + "UNIQUE (" + PlaylistsColumns.PLAYLIST_ID + ") ON CONFLICT IGNORE)"); |
264 | 206 | 207 | ||
265 | 207 | // Create the play queue playlist. | 208 | // Create the play queue playlist. |
266 | 208 | 209 | ||
267 | === modified file 'src/com/ubuntuone/android/music/provider/MusicProvider.java' | |||
268 | --- src/com/ubuntuone/android/music/provider/MusicProvider.java 2012-11-22 10:23:21 +0000 | |||
269 | +++ src/com/ubuntuone/android/music/provider/MusicProvider.java 2012-11-28 17:49:20 +0000 | |||
270 | @@ -602,18 +602,18 @@ | |||
271 | 602 | final String playlistId = Playlists.getPlaylistId(uri); | 602 | final String playlistId = Playlists.getPlaylistId(uri); |
272 | 603 | return builder.table(Tables.PLAYLIST_SONGS_JOIN_SONGS) | 603 | return builder.table(Tables.PLAYLIST_SONGS_JOIN_SONGS) |
273 | 604 | .where(PlaylistSongs.PLAYLIST_ID + "=?", playlistId) | 604 | .where(PlaylistSongs.PLAYLIST_ID + "=?", playlistId) |
276 | 605 | .mapToTable(Songs._ID, Tables.SONGS) | 605 | .mapToTable(PlaylistSongs._ID, Tables.PLAYLISTS_SONGS) |
277 | 606 | .mapToTable(Songs.SONG_ID, Tables.SONGS); | 606 | .mapToTable(PlaylistSongs.SONG_ID, Tables.SONGS); |
278 | 607 | } | 607 | } |
279 | 608 | case PLAYLISTS_ID_SONGS_ID: { | 608 | case PLAYLISTS_ID_SONGS_ID: { |
280 | 609 | final String playlistId = Playlists.getPlaylistId(uri); | 609 | final String playlistId = Playlists.getPlaylistId(uri); |
281 | 610 | final String songId = Playlists.getSongId(uri); | 610 | final String songId = Playlists.getSongId(uri); |
283 | 611 | return builder.table(Tables.PLAYLISTS_SONGS) | 611 | return builder.table(Tables.PLAYLIST_SONGS_JOIN_SONGS) |
284 | 612 | .where(PlaylistSongs.PLAYLIST_ID + "=?", playlistId) | 612 | .where(PlaylistSongs.PLAYLIST_ID + "=?", playlistId) |
285 | 613 | .where(PlaylistSongs.SONG_ID + "=?", songId) | 613 | .where(PlaylistSongs.SONG_ID + "=?", songId) |
289 | 614 | .mapToTable(Songs._ID, Tables.SONGS) | 614 | .mapToTable(PlaylistSongs._ID, Tables.PLAYLISTS_SONGS) |
290 | 615 | .mapToTable(Songs.SONG_ID, Tables.SONGS) | 615 | .mapToTable(PlaylistSongs.SONG_ID, Tables.SONGS) |
291 | 616 | .mapToTable(Songs.STARRED, Tables.SONGS); | 616 | .mapToTable(PlaylistSongs.STARRED, Tables.SONGS); |
292 | 617 | } | 617 | } |
293 | 618 | 618 | ||
294 | 619 | case GENRES: { | 619 | case GENRES: { |
295 | 620 | 620 | ||
296 | === modified file 'src/com/ubuntuone/android/music/provider/MusicProviderUtils.java' | |||
297 | --- src/com/ubuntuone/android/music/provider/MusicProviderUtils.java 2012-11-21 15:03:12 +0000 | |||
298 | +++ src/com/ubuntuone/android/music/provider/MusicProviderUtils.java 2012-11-28 17:49:20 +0000 | |||
299 | @@ -23,6 +23,7 @@ | |||
300 | 23 | 23 | ||
301 | 24 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; | 24 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; |
302 | 25 | 25 | ||
303 | 26 | import java.util.ArrayList; | ||
304 | 26 | import java.util.Random; | 27 | import java.util.Random; |
305 | 27 | 28 | ||
306 | 28 | import android.content.ContentResolver; | 29 | import android.content.ContentResolver; |
307 | @@ -208,11 +209,14 @@ | |||
308 | 208 | 209 | ||
309 | 209 | public static int getPlaylistSongCount(Context context, Uri playlistUri) { | 210 | public static int getPlaylistSongCount(Context context, Uri playlistUri) { |
310 | 210 | ContentResolver resolver = context.getContentResolver(); | 211 | ContentResolver resolver = context.getContentResolver(); |
311 | 212 | String playlistId = Playlists.getPlaylistId(playlistUri); | ||
312 | 213 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri(playlistId); | ||
313 | 214 | |||
314 | 211 | String[] projection = new String[] { Songs._ID }; | 215 | String[] projection = new String[] { Songs._ID }; |
315 | 212 | Cursor cursor = null; | 216 | Cursor cursor = null; |
316 | 213 | int count = -1; | 217 | int count = -1; |
317 | 214 | try { | 218 | try { |
319 | 215 | cursor = resolver.query(playlistUri, projection, null, null, null); | 219 | cursor = resolver.query(playlistSongsUri, projection, null, null, null); |
320 | 216 | count = (cursor != null) ? cursor.getCount() : 0; | 220 | count = (cursor != null) ? cursor.getCount() : 0; |
321 | 217 | } finally { | 221 | } finally { |
322 | 218 | if (cursor != null) cursor.close(); | 222 | if (cursor != null) cursor.close(); |
323 | @@ -220,6 +224,28 @@ | |||
324 | 220 | return count; | 224 | return count; |
325 | 221 | } | 225 | } |
326 | 222 | 226 | ||
327 | 227 | public static ArrayList<String> getPlaylistSongIdList(Context context, String playlistId) { | ||
328 | 228 | ContentResolver resolver = context.getContentResolver(); | ||
329 | 229 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri(playlistId); | ||
330 | 230 | ArrayList<String> songIdList = new ArrayList<String>(); | ||
331 | 231 | |||
332 | 232 | String[] projection = new String[] { PlaylistSongs.SONG_ID }; | ||
333 | 233 | Cursor cursor = null; | ||
334 | 234 | try { | ||
335 | 235 | cursor = resolver.query(playlistSongsUri, projection, null, null, null); | ||
336 | 236 | if (cursor != null && cursor.isBeforeFirst()) { | ||
337 | 237 | while (cursor.moveToNext()) { | ||
338 | 238 | String songId = cursor.getString(cursor.getColumnIndex(PlaylistSongs.SONG_ID)); | ||
339 | 239 | songIdList.add(songId); | ||
340 | 240 | } | ||
341 | 241 | } | ||
342 | 242 | } finally { | ||
343 | 243 | if (cursor != null) cursor.close(); | ||
344 | 244 | } | ||
345 | 245 | |||
346 | 246 | return songIdList; | ||
347 | 247 | } | ||
348 | 248 | |||
349 | 223 | public static int getPlayQueueSongCount(Context context) { | 249 | public static int getPlayQueueSongCount(Context context) { |
350 | 224 | Uri playQueueUri = Playlists.buildPlaylistSongsUri(QUEUE_ID); | 250 | Uri playQueueUri = Playlists.buildPlaylistSongsUri(QUEUE_ID); |
351 | 225 | return getPlaylistSongCount(context, playQueueUri); | 251 | return getPlaylistSongCount(context, playQueueUri); |
352 | @@ -236,14 +262,55 @@ | |||
353 | 236 | Uri playQueueUri = Playlists.buildPlaylistSongsUri(MusicProviderUtils.QUEUE_ID); | 262 | Uri playQueueUri = Playlists.buildPlaylistSongsUri(MusicProviderUtils.QUEUE_ID); |
354 | 237 | clearPlaylist(context, playQueueUri); | 263 | clearPlaylist(context, playQueueUri); |
355 | 238 | } | 264 | } |
357 | 239 | 265 | ||
358 | 266 | /** | ||
359 | 267 | * Updates playlist song count, saves one request to the server upon | ||
360 | 268 | * enqueuing content. | ||
361 | 269 | * | ||
362 | 270 | * @param context | ||
363 | 271 | * The context to use. | ||
364 | 272 | * @param playlistUri | ||
365 | 273 | * Playlist Uri of which song count to update. | ||
366 | 274 | */ | ||
367 | 275 | public static void updatePlaylistSongCount(Context context, Uri playlistUri) { | ||
368 | 276 | ContentResolver resolver = context.getContentResolver(); | ||
369 | 277 | ContentValues values = new ContentValues(); | ||
370 | 278 | int songCount = MusicProviderUtils.getPlaylistSongCount(context, playlistUri); | ||
371 | 279 | values.put(Playlists.PLAYLIST_SONG_COUNT, songCount); | ||
372 | 280 | resolver.update(playlistUri, values, null, null); | ||
373 | 281 | } | ||
374 | 282 | |||
375 | 283 | /** | ||
376 | 284 | * Flags the playlist as dirty for sync up. Next time metadata is refreshed, | ||
377 | 285 | * dirty playlists are first saved to the server. | ||
378 | 286 | * | ||
379 | 287 | * @param context | ||
380 | 288 | * The context to use. | ||
381 | 289 | * @param playlistUri | ||
382 | 290 | * Uri of the playlist to flag. | ||
383 | 291 | * @param isDirty | ||
384 | 292 | * true to mark for sync up, false otherwise. | ||
385 | 293 | */ | ||
386 | 294 | public static void flagPlaylistForSync(Context context, Uri playlistUri, boolean isDirty) { | ||
387 | 295 | ContentResolver resolver = context.getContentResolver(); | ||
388 | 296 | ContentValues values = new ContentValues(); | ||
389 | 297 | values.put(Playlists.DIRTY, isDirty); | ||
390 | 298 | resolver.update(playlistUri, values, null, null); | ||
391 | 299 | } | ||
392 | 300 | |||
393 | 240 | public static void enqueueSong(Context context, Uri songUri, Uri playlistUri) { | 301 | public static void enqueueSong(Context context, Uri songUri, Uri playlistUri) { |
394 | 241 | ContentResolver resolver = context.getContentResolver(); | 302 | ContentResolver resolver = context.getContentResolver(); |
395 | 242 | String playlistId = Playlists.getPlaylistId(playlistUri); | 303 | String playlistId = Playlists.getPlaylistId(playlistUri); |
396 | 243 | String songId = Songs.getSongId(songUri); | 304 | String songId = Songs.getSongId(songUri); |
397 | 305 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri(playlistId); | ||
398 | 244 | 306 | ||
399 | 245 | ContentValues values = MusicContentValues.forPlaylistSong(playlistId, songId); | 307 | ContentValues values = MusicContentValues.forPlaylistSong(playlistId, songId); |
401 | 246 | resolver.insert(playlistUri, values); | 308 | resolver.insert(playlistSongsUri, values); |
402 | 309 | |||
403 | 310 | if (!QUEUE_ID.equals(playlistId)) { | ||
404 | 311 | updatePlaylistSongCount(context, playlistUri); | ||
405 | 312 | flagPlaylistForSync(context, playlistUri, true); | ||
406 | 313 | } | ||
407 | 247 | } | 314 | } |
408 | 248 | 315 | ||
409 | 249 | public static void enqueueSong(Context context, Uri songUri) { | 316 | public static void enqueueSong(Context context, Uri songUri) { |
410 | 250 | 317 | ||
411 | === modified file 'src/com/ubuntuone/android/music/service/MusicService.java' | |||
412 | --- src/com/ubuntuone/android/music/service/MusicService.java 2012-11-21 15:03:12 +0000 | |||
413 | +++ src/com/ubuntuone/android/music/service/MusicService.java 2012-11-28 17:49:20 +0000 | |||
414 | @@ -41,6 +41,7 @@ | |||
415 | 41 | import android.content.Context; | 41 | import android.content.Context; |
416 | 42 | import android.content.Intent; | 42 | import android.content.Intent; |
417 | 43 | import android.content.SharedPreferences; | 43 | import android.content.SharedPreferences; |
418 | 44 | import android.database.sqlite.SQLiteDatabaseLockedException; | ||
419 | 44 | import android.media.AudioManager; | 45 | import android.media.AudioManager; |
420 | 45 | import android.media.MediaPlayer; | 46 | import android.media.MediaPlayer; |
421 | 46 | import android.media.MediaPlayer.OnErrorListener; | 47 | import android.media.MediaPlayer.OnErrorListener; |
422 | @@ -57,6 +58,7 @@ | |||
423 | 57 | import com.ubuntuone.android.music.UbuntuOneMusic; | 58 | import com.ubuntuone.android.music.UbuntuOneMusic; |
424 | 58 | import com.ubuntuone.android.music.model.PlayerState; | 59 | import com.ubuntuone.android.music.model.PlayerState; |
425 | 59 | import com.ubuntuone.android.music.model.Song; | 60 | import com.ubuntuone.android.music.model.Song; |
426 | 61 | import com.ubuntuone.android.music.provider.MusicContract.Songs; | ||
427 | 60 | import com.ubuntuone.android.music.provider.MusicProviderUtils; | 62 | import com.ubuntuone.android.music.provider.MusicProviderUtils; |
428 | 61 | import com.ubuntuone.android.music.util.UIUtils; | 63 | import com.ubuntuone.android.music.util.UIUtils; |
429 | 62 | import com.ubuntuone.api.music.U1MusicAPI; | 64 | import com.ubuntuone.api.music.U1MusicAPI; |
430 | @@ -123,9 +125,13 @@ | |||
431 | 123 | this.mShufflePlay = sharedPrefs.getBoolean(SHUFFLE_PREFERENCE_KEY, false); | 125 | this.mShufflePlay = sharedPrefs.getBoolean(SHUFFLE_PREFERENCE_KEY, false); |
432 | 124 | this.mRepeatPlay = sharedPrefs.getBoolean(REPEAT_PREFERENCE_KEY, false); | 126 | this.mRepeatPlay = sharedPrefs.getBoolean(REPEAT_PREFERENCE_KEY, false); |
433 | 125 | 127 | ||
437 | 126 | Uri songUri = MusicProviderUtils.getPlayingSong(this); | 128 | try { |
438 | 127 | if (songUri != null) { | 129 | Uri songUri = MusicProviderUtils.getPlayingSong(this); |
439 | 128 | mCurrentPlaying = new Song(this, songUri); | 130 | if (songUri != null) { |
440 | 131 | mCurrentPlaying = new Song(this, songUri); | ||
441 | 132 | } | ||
442 | 133 | } catch (SQLiteDatabaseLockedException e) { | ||
443 | 134 | // Ignore. Assume no song has been playing. | ||
444 | 129 | } | 135 | } |
445 | 130 | } | 136 | } |
446 | 131 | 137 | ||
447 | @@ -325,8 +331,13 @@ | |||
448 | 325 | } | 331 | } |
449 | 326 | 332 | ||
450 | 327 | private synchronized void setCurrentPlaying(Uri uri) { | 333 | private synchronized void setCurrentPlaying(Uri uri) { |
453 | 328 | MusicProviderUtils.setPlayingSong(this, uri); | 334 | // Make sure this is a song Uri, rather than playlist song Uri. |
454 | 329 | this.mCurrentPlaying = new Song(this, uri); | 335 | // This has to be changed when "now playing" column is moved to the PlaylistSongs table. |
455 | 336 | String songId = Songs.getSongId(uri); | ||
456 | 337 | Uri songUri = Songs.buildSongUri(songId); | ||
457 | 338 | |||
458 | 339 | MusicProviderUtils.setPlayingSong(this, songUri); | ||
459 | 340 | this.mCurrentPlaying = new Song(this, songUri); | ||
460 | 330 | callbackOnSongChanged(); | 341 | callbackOnSongChanged(); |
461 | 331 | if (mCurrentPlaying.isCompleteFileAvailable()) { | 342 | if (mCurrentPlaying.isCompleteFileAvailable()) { |
462 | 332 | callbackOnSongDownload(uri, 100); | 343 | callbackOnSongDownload(uri, 100); |
463 | 333 | 344 | ||
464 | === modified file 'src/com/ubuntuone/android/music/service/SyncService.java' | |||
465 | --- src/com/ubuntuone/android/music/service/SyncService.java 2012-11-28 17:49:20 +0000 | |||
466 | +++ src/com/ubuntuone/android/music/service/SyncService.java 2012-11-28 17:49:20 +0000 | |||
467 | @@ -22,12 +22,16 @@ | |||
468 | 22 | package com.ubuntuone.android.music.service; | 22 | package com.ubuntuone.android.music.service; |
469 | 23 | 23 | ||
470 | 24 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; | 24 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; |
471 | 25 | |||
472 | 26 | import java.util.ArrayList; | ||
473 | 27 | |||
474 | 25 | import android.app.IntentService; | 28 | import android.app.IntentService; |
475 | 26 | import android.content.ContentResolver; | 29 | import android.content.ContentResolver; |
476 | 27 | import android.content.Context; | 30 | import android.content.Context; |
477 | 28 | import android.content.Intent; | 31 | import android.content.Intent; |
478 | 29 | import android.database.Cursor; | 32 | import android.database.Cursor; |
479 | 30 | import android.database.sqlite.SQLiteDatabase; | 33 | import android.database.sqlite.SQLiteDatabase; |
480 | 34 | import android.net.Uri; | ||
481 | 31 | import android.os.Bundle; | 35 | import android.os.Bundle; |
482 | 32 | import android.os.ResultReceiver; | 36 | import android.os.ResultReceiver; |
483 | 33 | import android.util.Log; | 37 | import android.util.Log; |
484 | @@ -58,6 +62,7 @@ | |||
485 | 58 | import com.ubuntuone.api.music.model.U1Song; | 62 | import com.ubuntuone.api.music.model.U1Song; |
486 | 59 | import com.ubuntuone.api.music.request.U1AlbumListener; | 63 | import com.ubuntuone.api.music.request.U1AlbumListener; |
487 | 60 | import com.ubuntuone.api.music.request.U1ArtistListener; | 64 | import com.ubuntuone.api.music.request.U1ArtistListener; |
488 | 65 | import com.ubuntuone.api.music.request.U1CallbackListener; | ||
489 | 61 | import com.ubuntuone.api.music.request.U1PlaylistListener; | 66 | import com.ubuntuone.api.music.request.U1PlaylistListener; |
490 | 62 | import com.ubuntuone.api.music.request.U1SongListener; | 67 | import com.ubuntuone.api.music.request.U1SongListener; |
491 | 63 | 68 | ||
492 | @@ -67,6 +72,8 @@ | |||
493 | 67 | 72 | ||
494 | 68 | public static final String ACTION_SYNC_MUSIC_METADATA = | 73 | public static final String ACTION_SYNC_MUSIC_METADATA = |
495 | 69 | "com.ubuntuone.android.music.ACTION_SYNC_MUSIC_METADATA"; | 74 | "com.ubuntuone.android.music.ACTION_SYNC_MUSIC_METADATA"; |
496 | 75 | public static final String ACTION_SYNC_PLAYLISTS = | ||
497 | 76 | "com.ubuntuone.android.music.ACTION_SYNC_PLAYLISTS"; | ||
498 | 70 | 77 | ||
499 | 71 | public static final String EXTRA_RECEIVER = "result_receiver"; | 78 | public static final String EXTRA_RECEIVER = "result_receiver"; |
500 | 72 | public static final String EXTRA_LOADER_ID = "loader_id"; | 79 | public static final String EXTRA_LOADER_ID = "loader_id"; |
501 | @@ -103,19 +110,25 @@ | |||
502 | 103 | @Override | 110 | @Override |
503 | 104 | protected void onHandleIntent(Intent intent) { | 111 | protected void onHandleIntent(Intent intent) { |
504 | 105 | final String action = intent.getAction(); | 112 | final String action = intent.getAction(); |
505 | 113 | if (action == null) return; | ||
506 | 106 | mReceiver = intent.getParcelableExtra(EXTRA_RECEIVER); | 114 | mReceiver = intent.getParcelableExtra(EXTRA_RECEIVER); |
512 | 107 | if (action != null && ACTION_SYNC_MUSIC_METADATA.equals(action)) { | 115 | mTimeSyncStarted = System.currentTimeMillis(); |
513 | 108 | mTimeSyncStarted = System.currentTimeMillis(); | 116 | if (mApi != null && UbuntuOneMusic.SHOULD_SYNC) { |
514 | 109 | if (mApi != null && UbuntuOneMusic.SHOULD_SYNC) { | 117 | sSyncStatus = SYNC_STARTED; |
515 | 110 | sSyncStatus = SYNC_STARTED; | 118 | if (mReceiver != null) mReceiver.send(SYNC_STARTED, Bundle.EMPTY); |
516 | 111 | if (mReceiver != null) mReceiver.send(SYNC_STARTED, Bundle.EMPTY); | 119 | |
517 | 120 | if (ACTION_SYNC_MUSIC_METADATA.equals(action)) { | ||
518 | 121 | syncPlaylistMetadata(); | ||
519 | 112 | syncMusicMetadata(); | 122 | syncMusicMetadata(); |
522 | 113 | if (mReceiver != null) mReceiver.send(SYNC_FINISHED, Bundle.EMPTY); | 123 | } else if (ACTION_SYNC_PLAYLISTS.equals(action)) { |
523 | 114 | sSyncStatus = SYNC_FINISHED; | 124 | syncPlaylistMetadata(); |
524 | 115 | } | 125 | } |
527 | 116 | long now = System.currentTimeMillis(); | 126 | |
528 | 117 | Log.i(TAG, "Ubuntu One music metadata sync sync took " + (now - mTimeSyncStarted) + " ms"); | 127 | if (mReceiver != null) mReceiver.send(SYNC_FINISHED, Bundle.EMPTY); |
529 | 128 | sSyncStatus = SYNC_FINISHED; | ||
530 | 118 | } | 129 | } |
531 | 130 | long now = System.currentTimeMillis(); | ||
532 | 131 | Log.i(TAG, "Ubuntu One music metadata sync sync took " + (now - mTimeSyncStarted) + " ms"); | ||
533 | 119 | } | 132 | } |
534 | 120 | 133 | ||
535 | 121 | private void syncMusicMetadata() { | 134 | private void syncMusicMetadata() { |
536 | @@ -130,6 +143,10 @@ | |||
537 | 130 | } | 143 | } |
538 | 131 | } | 144 | } |
539 | 132 | 145 | ||
540 | 146 | private void syncPlaylistMetadata() { | ||
541 | 147 | syncUpPlaylists(); | ||
542 | 148 | } | ||
543 | 149 | |||
544 | 133 | private void syncArtists() { | 150 | private void syncArtists() { |
545 | 134 | final long timeMillis = System.currentTimeMillis(); | 151 | final long timeMillis = System.currentTimeMillis(); |
546 | 135 | mApi.getArtists(mArtistListener); | 152 | mApi.getArtists(mArtistListener); |
547 | @@ -158,6 +175,38 @@ | |||
548 | 158 | Log.i(TAG, "Playlists sync took " + (nowMillis - timeMillis) + "ms"); | 175 | Log.i(TAG, "Playlists sync took " + (nowMillis - timeMillis) + "ms"); |
549 | 159 | } | 176 | } |
550 | 160 | 177 | ||
551 | 178 | private void syncUpPlaylists() { | ||
552 | 179 | final long timeMillis = System.currentTimeMillis(); | ||
553 | 180 | Cursor cursor = null; | ||
554 | 181 | try { | ||
555 | 182 | String[] projection = new String[] { Playlists.PLAYLIST_ID, Playlists.PLAYLIST_NAME }; | ||
556 | 183 | String selection = Playlists.DIRTY + "=1"; | ||
557 | 184 | cursor = getContentResolver().query(Playlists.CONTENT_URI, | ||
558 | 185 | projection, selection, null, null); | ||
559 | 186 | if (cursor != null && cursor.isBeforeFirst()) { | ||
560 | 187 | while (cursor.moveToNext()) { | ||
561 | 188 | final String playlistId = cursor.getString(cursor.getColumnIndex(Playlists.PLAYLIST_ID)); | ||
562 | 189 | String playlistName = cursor.getString(cursor.getColumnIndex(Playlists.PLAYLIST_NAME)); | ||
563 | 190 | ArrayList<String> songIdList = MusicProviderUtils.getPlaylistSongIdList(this, playlistId); | ||
564 | 191 | |||
565 | 192 | mApi.updatePlaylist(playlistId, playlistName, songIdList, new U1CallbackListener() { | ||
566 | 193 | @Override | ||
567 | 194 | public void onSuccess() { | ||
568 | 195 | Log.i(TAG, "Updated playlist: " + playlistId); | ||
569 | 196 | Uri playlistUri = Playlists.buildPlaylistUri(playlistId); | ||
570 | 197 | MusicProviderUtils.flagPlaylistForSync(SyncService.this, playlistUri, false); | ||
571 | 198 | // TODO Persist playlist entity from response once CSRF fix is rolled out. | ||
572 | 199 | } | ||
573 | 200 | }); | ||
574 | 201 | } | ||
575 | 202 | } | ||
576 | 203 | } finally { | ||
577 | 204 | if (cursor != null) cursor.close(); | ||
578 | 205 | } | ||
579 | 206 | final long nowMillis = System.currentTimeMillis(); | ||
580 | 207 | Log.i(TAG, "Playlist songs sync up took " + (nowMillis - timeMillis) + "ms"); | ||
581 | 208 | } | ||
582 | 209 | |||
583 | 161 | private void syncPlaylistSongs() { | 210 | private void syncPlaylistSongs() { |
584 | 162 | final long timeMillis = System.currentTimeMillis(); | 211 | final long timeMillis = System.currentTimeMillis(); |
585 | 163 | Cursor cursor = null; | 212 | Cursor cursor = null; |
586 | @@ -175,7 +224,7 @@ | |||
587 | 175 | if (cursor != null) cursor.close(); | 224 | if (cursor != null) cursor.close(); |
588 | 176 | } | 225 | } |
589 | 177 | final long nowMillis = System.currentTimeMillis(); | 226 | final long nowMillis = System.currentTimeMillis(); |
591 | 178 | Log.i(TAG, "Playlist songs sync took " + (nowMillis - timeMillis) + "ms"); | 227 | Log.i(TAG, "Playlist songs sync down took " + (nowMillis - timeMillis) + "ms"); |
592 | 179 | } | 228 | } |
593 | 180 | 229 | ||
594 | 181 | private U1ArtistListener mArtistListener = new U1ArtistListener() { | 230 | private U1ArtistListener mArtistListener = new U1ArtistListener() { |
595 | 182 | 231 | ||
596 | === modified file 'src/com/ubuntuone/android/music/ui/AlbumsFragment.java' | |||
597 | --- src/com/ubuntuone/android/music/ui/AlbumsFragment.java 2012-11-22 10:23:21 +0000 | |||
598 | +++ src/com/ubuntuone/android/music/ui/AlbumsFragment.java 2012-11-28 17:49:20 +0000 | |||
599 | @@ -25,6 +25,7 @@ | |||
600 | 25 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; | 25 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; |
601 | 26 | import android.app.Activity; | 26 | import android.app.Activity; |
602 | 27 | import android.content.Context; | 27 | import android.content.Context; |
603 | 28 | import android.content.Intent; | ||
604 | 28 | import android.database.Cursor; | 29 | import android.database.Cursor; |
605 | 29 | import android.net.Uri; | 30 | import android.net.Uri; |
606 | 30 | import android.os.Bundle; | 31 | import android.os.Bundle; |
607 | @@ -187,7 +188,13 @@ | |||
608 | 187 | } | 188 | } |
609 | 188 | 189 | ||
610 | 189 | private boolean onAddToPlaylistContextItemSelected(int position) { | 190 | private boolean onAddToPlaylistContextItemSelected(int position) { |
612 | 190 | // TODO | 191 | Cursor cursor = (Cursor) mListView.getItemAtPosition(position); |
613 | 192 | String albumId = cursor.getString(cursor.getColumnIndex(Albums.ALBUM_ID)); | ||
614 | 193 | Uri albumUri = Albums.buildAlbumUri(albumId); | ||
615 | 194 | |||
616 | 195 | Intent intent = new Intent(getActivity(), PlaylistsActivity.class); | ||
617 | 196 | intent.putExtra(PlaylistsActivity.EXTRA_ENQUEUE_CONTENT_ID, albumUri); | ||
618 | 197 | startActivity(intent); | ||
619 | 191 | return true; | 198 | return true; |
620 | 192 | } | 199 | } |
621 | 193 | 200 | ||
622 | 194 | 201 | ||
623 | === modified file 'src/com/ubuntuone/android/music/ui/HomeActivity.java' | |||
624 | --- src/com/ubuntuone/android/music/ui/HomeActivity.java 2012-11-21 15:03:12 +0000 | |||
625 | +++ src/com/ubuntuone/android/music/ui/HomeActivity.java 2012-11-28 17:49:20 +0000 | |||
626 | @@ -44,8 +44,10 @@ | |||
627 | 44 | import android.support.v4.app.LoaderManager; | 44 | import android.support.v4.app.LoaderManager; |
628 | 45 | import android.support.v4.content.Loader; | 45 | import android.support.v4.content.Loader; |
629 | 46 | import android.support.v4.view.ViewPager; | 46 | import android.support.v4.view.ViewPager; |
630 | 47 | import android.support.v4.widget.CursorAdapter; | ||
631 | 47 | import android.view.View; | 48 | import android.view.View; |
632 | 48 | import android.view.View.OnClickListener; | 49 | import android.view.View.OnClickListener; |
633 | 50 | import android.widget.Adapter; | ||
634 | 49 | import android.widget.LinearLayout; | 51 | import android.widget.LinearLayout; |
635 | 50 | import android.widget.Toast; | 52 | import android.widget.Toast; |
636 | 51 | 53 | ||
637 | @@ -55,22 +57,26 @@ | |||
638 | 55 | import com.actionbarsherlock.view.MenuItem; | 57 | import com.actionbarsherlock.view.MenuItem; |
639 | 56 | import com.ubuntuone.android.music.R; | 58 | import com.ubuntuone.android.music.R; |
640 | 57 | import com.ubuntuone.android.music.UbuntuOneMusic; | 59 | import com.ubuntuone.android.music.UbuntuOneMusic; |
641 | 60 | import com.ubuntuone.android.music.adapter.U1PlaylistAdapter; | ||
642 | 61 | import com.ubuntuone.android.music.adapter.U1PlaylistAdapter.Position; | ||
643 | 58 | import com.ubuntuone.android.music.adapter.holder.NowPlayingViewHolder; | 62 | import com.ubuntuone.android.music.adapter.holder.NowPlayingViewHolder; |
644 | 59 | import com.ubuntuone.android.music.model.PlayerState; | 63 | import com.ubuntuone.android.music.model.PlayerState; |
645 | 64 | import com.ubuntuone.android.music.provider.MusicContract.Playlists; | ||
646 | 60 | import com.ubuntuone.android.music.provider.MusicContract.Songs; | 65 | import com.ubuntuone.android.music.provider.MusicContract.Songs; |
647 | 61 | import com.ubuntuone.android.music.provider.MusicProviderUtils; | 66 | import com.ubuntuone.android.music.provider.MusicProviderUtils; |
648 | 62 | import com.ubuntuone.android.music.service.MusicService; | 67 | import com.ubuntuone.android.music.service.MusicService; |
649 | 63 | import com.ubuntuone.android.music.service.MusicServiceBinder; | 68 | import com.ubuntuone.android.music.service.MusicServiceBinder; |
650 | 64 | import com.ubuntuone.android.music.service.MusicServiceCallback; | 69 | import com.ubuntuone.android.music.service.MusicServiceCallback; |
651 | 65 | import com.ubuntuone.android.music.service.SyncService; | 70 | import com.ubuntuone.android.music.service.SyncService; |
652 | 71 | import com.ubuntuone.android.music.ui.PlaylistsFragment.OnPlaylistSelectedListener; | ||
653 | 66 | import com.ubuntuone.android.music.ui.dialog.InputAlertDialog.InputAlertDialogListener; | 72 | import com.ubuntuone.android.music.ui.dialog.InputAlertDialog.InputAlertDialogListener; |
654 | 67 | import com.ubuntuone.android.music.util.AccountUtils; | 73 | import com.ubuntuone.android.music.util.AccountUtils; |
655 | 68 | import com.ubuntuone.android.music.util.U1ImageDownloader; | 74 | import com.ubuntuone.android.music.util.U1ImageDownloader; |
656 | 69 | import com.ubuntuone.android.music.util.UIUtils; | 75 | import com.ubuntuone.android.music.util.UIUtils; |
657 | 70 | 76 | ||
658 | 71 | public class HomeActivity extends SherlockFragmentActivity implements ActionBar.TabListener, | 77 | public class HomeActivity extends SherlockFragmentActivity implements ActionBar.TabListener, |
661 | 72 | ViewPager.OnPageChangeListener, OnClickListener, InputAlertDialogListener, | 78 | ViewPager.OnPageChangeListener, OnClickListener, OnPlaylistSelectedListener, |
662 | 73 | MusicServiceCallback | 79 | InputAlertDialogListener, MusicServiceCallback |
663 | 74 | { | 80 | { |
664 | 75 | @SuppressWarnings("unused") | 81 | @SuppressWarnings("unused") |
665 | 76 | private static final String TAG = makeLogTag(HomeActivity.class); | 82 | private static final String TAG = makeLogTag(HomeActivity.class); |
666 | @@ -80,7 +86,7 @@ | |||
667 | 80 | private static final int REQUEST_AUTHENTICATE = 1; | 86 | private static final int REQUEST_AUTHENTICATE = 1; |
668 | 81 | 87 | ||
669 | 82 | /* package */ static final int PLEASE_WAIT_DIALOG_ID = 1; | 88 | /* package */ static final int PLEASE_WAIT_DIALOG_ID = 1; |
671 | 83 | /* package */ static final int INFO_DIALOG_ID = 2; | 89 | /* package */ static final int ERROR_DIALOG_ID = 2; |
672 | 84 | /* package */ static final int CREATE_PLAYLIST_DIALOG_ID = 3; | 90 | /* package */ static final int CREATE_PLAYLIST_DIALOG_ID = 3; |
673 | 85 | 91 | ||
674 | 86 | private Handler mHandler = new Handler(); | 92 | private Handler mHandler = new Handler(); |
675 | @@ -572,7 +578,47 @@ | |||
676 | 572 | mShuffleAllSongsTask = null; | 578 | mShuffleAllSongsTask = null; |
677 | 573 | } | 579 | } |
678 | 574 | } | 580 | } |
680 | 575 | 581 | ||
681 | 582 | @Override | ||
682 | 583 | public void onPlaylistSelected(Adapter adapter, int position, boolean hasHeaders) { | ||
683 | 584 | if (hasHeaders && position < U1PlaylistAdapter.Position.COUNT) { | ||
684 | 585 | switch (position) { | ||
685 | 586 | case Position.STARRED: { | ||
686 | 587 | int count = MusicProviderUtils.getStarredSongCount(this); | ||
687 | 588 | PlaylistActivity.startFrom(this, MusicProviderUtils.STARRED_ID, | ||
688 | 589 | getString(R.string.starred), count); | ||
689 | 590 | break; | ||
690 | 591 | } | ||
691 | 592 | case Position.CACHED: { | ||
692 | 593 | int count = MusicProviderUtils.getCachedSongCount(this); | ||
693 | 594 | PlaylistActivity.startFrom(this, MusicProviderUtils.CACHED_ID, | ||
694 | 595 | getString(R.string.cached), count); | ||
695 | 596 | break; | ||
696 | 597 | } | ||
697 | 598 | case Position.QUEUED: { | ||
698 | 599 | PlayerActivity.startWithQueue(this); | ||
699 | 600 | break; | ||
700 | 601 | } | ||
701 | 602 | } | ||
702 | 603 | } else { | ||
703 | 604 | if (hasHeaders) position -= Position.COUNT; | ||
704 | 605 | |||
705 | 606 | Cursor cursor = ((CursorAdapter) adapter).getCursor(); | ||
706 | 607 | cursor.moveToPosition(position); | ||
707 | 608 | |||
708 | 609 | int songCount = cursor.getInt(cursor.getColumnIndex(Playlists.PLAYLIST_SONG_COUNT)); | ||
709 | 610 | if (songCount == 0) { | ||
710 | 611 | String title = cursor.getString(cursor.getColumnIndex(Playlists.PLAYLIST_NAME)); | ||
711 | 612 | String text = getString(R.string.playlist_is_empty, title); | ||
712 | 613 | if (!isFinishing()) { | ||
713 | 614 | Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); | ||
714 | 615 | } | ||
715 | 616 | } else { | ||
716 | 617 | PlaylistActivity.startFrom(this, cursor); | ||
717 | 618 | } | ||
718 | 619 | } | ||
719 | 620 | } | ||
720 | 621 | |||
721 | 576 | @Override | 622 | @Override |
722 | 577 | public void onClick(View v) { | 623 | public void onClick(View v) { |
723 | 578 | switch (v.getId()) { | 624 | switch (v.getId()) { |
724 | 579 | 625 | ||
725 | === modified file 'src/com/ubuntuone/android/music/ui/PlayerFragment.java' | |||
726 | --- src/com/ubuntuone/android/music/ui/PlayerFragment.java 2012-11-08 14:14:54 +0000 | |||
727 | +++ src/com/ubuntuone/android/music/ui/PlayerFragment.java 2012-11-28 17:49:20 +0000 | |||
728 | @@ -401,7 +401,7 @@ | |||
729 | 401 | 401 | ||
730 | 402 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri(MusicProviderUtils.QUEUE_ID); | 402 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri(MusicProviderUtils.QUEUE_ID); |
731 | 403 | CursorLoader loader = new CursorLoader(getSherlockActivity(), playlistSongsUri, | 403 | CursorLoader loader = new CursorLoader(getSherlockActivity(), playlistSongsUri, |
733 | 404 | Songs.DEFAULT_PROJECTION, null, null, PlaylistSongs.DEFAULT_SORT); | 404 | Songs.getDefaultProjection(), null, null, PlaylistSongs.DEFAULT_SORT); |
734 | 405 | 405 | ||
735 | 406 | setIsLoading(true); | 406 | setIsLoading(true); |
736 | 407 | return loader; | 407 | return loader; |
737 | 408 | 408 | ||
738 | === modified file 'src/com/ubuntuone/android/music/ui/PlaylistActivity.java' | |||
739 | --- src/com/ubuntuone/android/music/ui/PlaylistActivity.java 2012-11-08 14:14:54 +0000 | |||
740 | +++ src/com/ubuntuone/android/music/ui/PlaylistActivity.java 2012-11-28 17:49:20 +0000 | |||
741 | @@ -58,7 +58,6 @@ | |||
742 | 58 | @Override | 58 | @Override |
743 | 59 | protected void onCreate(Bundle savedInstanceState) { | 59 | protected void onCreate(Bundle savedInstanceState) { |
744 | 60 | super.onCreate(savedInstanceState); | 60 | super.onCreate(savedInstanceState); |
745 | 61 | // TODO Rename layout? | ||
746 | 62 | setContentView(R.layout.activity_collection); | 61 | setContentView(R.layout.activity_collection); |
747 | 63 | 62 | ||
748 | 64 | mPlaylistArt = (ImageView) findViewById(R.id.image); | 63 | mPlaylistArt = (ImageView) findViewById(R.id.image); |
749 | 65 | 64 | ||
750 | === modified file 'src/com/ubuntuone/android/music/ui/PlaylistsActivity.java' | |||
751 | --- src/com/ubuntuone/android/music/ui/PlaylistsActivity.java 2012-11-08 14:14:54 +0000 | |||
752 | +++ src/com/ubuntuone/android/music/ui/PlaylistsActivity.java 2012-11-28 17:49:20 +0000 | |||
753 | @@ -21,16 +21,158 @@ | |||
754 | 21 | 21 | ||
755 | 22 | package com.ubuntuone.android.music.ui; | 22 | package com.ubuntuone.android.music.ui; |
756 | 23 | 23 | ||
757 | 24 | import static com.ubuntuone.android.music.ui.HomeActivity.ERROR_DIALOG_ID; | ||
758 | 25 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; | ||
759 | 26 | import android.app.Activity; | ||
760 | 27 | import android.content.ContentResolver; | ||
761 | 28 | import android.content.Intent; | ||
762 | 29 | import android.database.Cursor; | ||
763 | 30 | import android.net.Uri; | ||
764 | 31 | import android.os.AsyncTask; | ||
765 | 32 | import android.os.Bundle; | ||
766 | 33 | import android.support.v4.app.LoaderManager; | ||
767 | 34 | import android.support.v4.content.Loader; | ||
768 | 35 | import android.support.v4.widget.CursorAdapter; | ||
769 | 36 | import android.util.Log; | ||
770 | 37 | import android.widget.Adapter; | ||
771 | 38 | import android.widget.Toast; | ||
772 | 39 | |||
773 | 24 | import com.actionbarsherlock.app.SherlockFragmentActivity; | 40 | import com.actionbarsherlock.app.SherlockFragmentActivity; |
774 | 41 | import com.actionbarsherlock.view.MenuItem; | ||
775 | 42 | import com.ubuntuone.android.music.R; | ||
776 | 25 | import com.ubuntuone.android.music.provider.MusicContract.Albums; | 43 | import com.ubuntuone.android.music.provider.MusicContract.Albums; |
777 | 26 | import com.ubuntuone.android.music.provider.MusicContract.Artists; | 44 | import com.ubuntuone.android.music.provider.MusicContract.Artists; |
778 | 45 | import com.ubuntuone.android.music.provider.MusicContract.Playlists; | ||
779 | 27 | import com.ubuntuone.android.music.provider.MusicContract.Songs; | 46 | import com.ubuntuone.android.music.provider.MusicContract.Songs; |
780 | 47 | import com.ubuntuone.android.music.provider.MusicProviderUtils; | ||
781 | 48 | import com.ubuntuone.android.music.service.SyncService; | ||
782 | 49 | import com.ubuntuone.android.music.ui.PlaylistsFragment.OnPlaylistSelectedListener; | ||
783 | 50 | import com.ubuntuone.android.music.ui.dialog.InfoAlertDialog.InfoAlertDialogListener; | ||
784 | 51 | import com.ubuntuone.android.music.util.UIUtils; | ||
785 | 28 | 52 | ||
787 | 29 | public class PlaylistsActivity extends SherlockFragmentActivity | 53 | public class PlaylistsActivity extends SherlockFragmentActivity implements |
788 | 54 | OnPlaylistSelectedListener, InfoAlertDialogListener | ||
789 | 30 | { | 55 | { |
795 | 31 | public static final String EXTRA_ENQUEUE_SONG_ID = Songs.SONG_ID; | 56 | private static final String TAG = makeLogTag(PlaylistActivity.class); |
796 | 32 | public static final String EXTRA_ENQUEUE_ALBUM_ID = Albums.ALBUM_ID; | 57 | |
797 | 33 | public static final String EXTRA_ENQUEUE_ARTIST_ID = Artists.ARTIST_ID; | 58 | public static final String EXTRA_ENQUEUE_CONTENT_ID = "content_uri"; |
798 | 34 | 59 | ||
799 | 35 | // TODO enqueue provided content to selected playlist, allow creating a playlist | 60 | private Uri mContentUri; |
800 | 61 | |||
801 | 62 | @Override | ||
802 | 63 | protected void onCreate(Bundle savedInstanceState) { | ||
803 | 64 | super.onCreate(savedInstanceState); | ||
804 | 65 | setContentView(R.layout.activity_playlists); | ||
805 | 66 | |||
806 | 67 | mContentUri = getIntent().getParcelableExtra(EXTRA_ENQUEUE_CONTENT_ID); | ||
807 | 68 | |||
808 | 69 | if (mContentUri == null) { | ||
809 | 70 | throw new IllegalStateException("You must provide content_uri which is " + | ||
810 | 71 | "to be added to a playlist."); | ||
811 | 72 | } | ||
812 | 73 | |||
813 | 74 | LoaderManager lm = getSupportLoaderManager(); | ||
814 | 75 | Loader<?> loader = lm.getLoader(R.id.playlist_songs_loader_id); | ||
815 | 76 | if (loader != null) { | ||
816 | 77 | loader.stopLoading(); | ||
817 | 78 | } | ||
818 | 79 | } | ||
819 | 80 | |||
820 | 81 | @Override | ||
821 | 82 | public boolean onOptionsItemSelected(MenuItem item) { | ||
822 | 83 | switch (item.getItemId()) { | ||
823 | 84 | case android.R.id.home: | ||
824 | 85 | finish(); | ||
825 | 86 | return true; | ||
826 | 87 | |||
827 | 88 | default: | ||
828 | 89 | return super.onOptionsItemSelected(item); | ||
829 | 90 | } | ||
830 | 91 | } | ||
831 | 92 | |||
832 | 93 | @Override | ||
833 | 94 | public void onPlaylistSelected(Adapter adapter, int position, boolean hasHeaders) { | ||
834 | 95 | if (hasHeaders) { | ||
835 | 96 | throw new IllegalArgumentException( | ||
836 | 97 | "PlaylistsActivity must not contain custom playlists."); | ||
837 | 98 | } | ||
838 | 99 | |||
839 | 100 | Cursor cursor = ((CursorAdapter) adapter).getCursor(); | ||
840 | 101 | cursor.moveToPosition(position); | ||
841 | 102 | |||
842 | 103 | String playlistId = cursor.getString(cursor.getColumnIndex(Playlists.PLAYLIST_ID)); | ||
843 | 104 | Uri playlistUri = Playlists.buildPlaylistUri(playlistId); | ||
844 | 105 | |||
845 | 106 | if (mContentUri != null) { | ||
846 | 107 | AppendToPlaylistTask appendTask = new AppendToPlaylistTask(); | ||
847 | 108 | appendTask.execute(playlistUri, mContentUri); | ||
848 | 109 | } | ||
849 | 110 | } | ||
850 | 111 | |||
851 | 112 | private class AppendToPlaylistTask extends AsyncTask<Uri, Void, Uri> { | ||
852 | 113 | @Override | ||
853 | 114 | protected Uri doInBackground(Uri... params) { | ||
854 | 115 | if (params.length != 2) { | ||
855 | 116 | throw new IllegalArgumentException( | ||
856 | 117 | "AppendToPlaylistTask takes two arguments, playlist uri and content uri"); | ||
857 | 118 | } | ||
858 | 119 | final Uri playlistUri = params[0]; | ||
859 | 120 | final Uri contentUri = params[1]; | ||
860 | 121 | |||
861 | 122 | ContentResolver resolver = getContentResolver(); | ||
862 | 123 | |||
863 | 124 | String mimeType = resolver.getType(contentUri); | ||
864 | 125 | Activity activity = PlaylistsActivity.this; | ||
865 | 126 | if (mimeType.equals(Artists.CONTENT_ITEM_TYPE)) { | ||
866 | 127 | Log.e(TAG, "artist"); | ||
867 | 128 | MusicProviderUtils.enqueueArtist(activity, contentUri, playlistUri); | ||
868 | 129 | } else if (mimeType.equals(Albums.CONTENT_ITEM_TYPE)) { | ||
869 | 130 | Log.e(TAG, "album"); | ||
870 | 131 | MusicProviderUtils.enqueueAlbum(activity, contentUri, playlistUri); | ||
871 | 132 | } else if (mimeType.equals(Songs.CONTENT_ITEM_TYPE)) { | ||
872 | 133 | Log.e(TAG, "song"); | ||
873 | 134 | MusicProviderUtils.enqueueSong(activity, contentUri, playlistUri); | ||
874 | 135 | } else { | ||
875 | 136 | Log.e(TAG, "Unknown content uri to enqueue to playlist: " + contentUri.toString()); | ||
876 | 137 | } | ||
877 | 138 | return playlistUri; | ||
878 | 139 | } | ||
879 | 140 | |||
880 | 141 | @Override | ||
881 | 142 | protected void onPostExecute(Uri playlistUri) { | ||
882 | 143 | if (playlistUri == null) { | ||
883 | 144 | Log.e(TAG, "PlaylistsActivity#AppendToPlaylistTask#onPostExecute null playlistUri"); | ||
884 | 145 | return; | ||
885 | 146 | } | ||
886 | 147 | |||
887 | 148 | String playlistName = null; | ||
888 | 149 | Cursor cursor = null; | ||
889 | 150 | try { | ||
890 | 151 | final String[] projection = new String[] { Playlists.PLAYLIST_NAME }; | ||
891 | 152 | cursor = getContentResolver().query(playlistUri, projection, null, null, null); | ||
892 | 153 | if (cursor != null && cursor.moveToFirst()) { | ||
893 | 154 | playlistName = cursor.getString(cursor.getColumnIndex(Playlists.PLAYLIST_NAME)); | ||
894 | 155 | } | ||
895 | 156 | } finally { | ||
896 | 157 | cursor.close(); | ||
897 | 158 | } | ||
898 | 159 | |||
899 | 160 | String msg = getString(R.string.added_to_fmt, playlistName); | ||
900 | 161 | Toast.makeText(PlaylistsActivity.this, msg, Toast.LENGTH_SHORT).show(); | ||
901 | 162 | |||
902 | 163 | if (UIUtils.isNetworkConnected(PlaylistsActivity.this)) { | ||
903 | 164 | Intent syncPlaylists = new Intent(SyncService.ACTION_SYNC_PLAYLISTS); | ||
904 | 165 | startService(syncPlaylists); | ||
905 | 166 | } | ||
906 | 167 | |||
907 | 168 | finish(); | ||
908 | 169 | } | ||
909 | 170 | } | ||
910 | 171 | |||
911 | 172 | @Override | ||
912 | 173 | public void onPositiveButtonClicked(int dialogId) { | ||
913 | 174 | if (dialogId == ERROR_DIALOG_ID) { | ||
914 | 175 | finish(); | ||
915 | 176 | } | ||
916 | 177 | } | ||
917 | 36 | } | 178 | } |
918 | 37 | 179 | ||
919 | === modified file 'src/com/ubuntuone/android/music/ui/PlaylistsFragment.java' | |||
920 | --- src/com/ubuntuone/android/music/ui/PlaylistsFragment.java 2012-11-22 10:23:21 +0000 | |||
921 | +++ src/com/ubuntuone/android/music/ui/PlaylistsFragment.java 2012-11-28 17:49:20 +0000 | |||
922 | @@ -21,7 +21,7 @@ | |||
923 | 21 | 21 | ||
924 | 22 | package com.ubuntuone.android.music.ui; | 22 | package com.ubuntuone.android.music.ui; |
925 | 23 | 23 | ||
927 | 24 | import static com.ubuntuone.android.music.ui.HomeActivity.INFO_DIALOG_ID; | 24 | import static com.ubuntuone.android.music.ui.HomeActivity.ERROR_DIALOG_ID; |
928 | 25 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; | 25 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; |
929 | 26 | 26 | ||
930 | 27 | import java.util.ArrayList; | 27 | import java.util.ArrayList; |
931 | @@ -30,7 +30,6 @@ | |||
932 | 30 | import android.content.ContentResolver; | 30 | import android.content.ContentResolver; |
933 | 31 | import android.content.Context; | 31 | import android.content.Context; |
934 | 32 | import android.database.Cursor; | 32 | import android.database.Cursor; |
935 | 33 | import android.net.Uri; | ||
936 | 34 | import android.os.AsyncTask; | 33 | import android.os.AsyncTask; |
937 | 35 | import android.os.Bundle; | 34 | import android.os.Bundle; |
938 | 36 | import android.support.v4.app.DialogFragment; | 35 | import android.support.v4.app.DialogFragment; |
939 | @@ -44,27 +43,26 @@ | |||
940 | 44 | import android.view.View; | 43 | import android.view.View; |
941 | 45 | import android.view.View.OnClickListener; | 44 | import android.view.View.OnClickListener; |
942 | 46 | import android.view.ViewGroup; | 45 | import android.view.ViewGroup; |
943 | 46 | import android.widget.Adapter; | ||
944 | 47 | import android.widget.Button; | 47 | import android.widget.Button; |
945 | 48 | import android.widget.ListView; | 48 | import android.widget.ListView; |
946 | 49 | import android.widget.Toast; | ||
947 | 50 | 49 | ||
948 | 51 | import com.actionbarsherlock.app.SherlockFragmentActivity; | 50 | import com.actionbarsherlock.app.SherlockFragmentActivity; |
949 | 52 | import com.ubuntuone.android.music.R; | 51 | import com.ubuntuone.android.music.R; |
950 | 53 | import com.ubuntuone.android.music.UbuntuOneMusic; | 52 | import com.ubuntuone.android.music.UbuntuOneMusic; |
951 | 54 | import com.ubuntuone.android.music.adapter.U1PlaylistAdapter; | 53 | import com.ubuntuone.android.music.adapter.U1PlaylistAdapter; |
952 | 55 | import com.ubuntuone.android.music.adapter.U1PlaylistAdapter.Position; | ||
953 | 56 | import com.ubuntuone.android.music.provider.MusicContract.Albums; | ||
954 | 57 | import com.ubuntuone.android.music.provider.MusicContract.Artists; | ||
955 | 58 | import com.ubuntuone.android.music.provider.MusicContract.Playlists; | 54 | import com.ubuntuone.android.music.provider.MusicContract.Playlists; |
956 | 59 | import com.ubuntuone.android.music.provider.MusicContract.Songs; | ||
957 | 60 | import com.ubuntuone.android.music.provider.MusicProviderUtils; | 55 | import com.ubuntuone.android.music.provider.MusicProviderUtils; |
958 | 56 | import com.ubuntuone.android.music.provider.dao.PlaylistDao; | ||
959 | 61 | import com.ubuntuone.android.music.ui.dialog.InfoAlertDialog; | 57 | import com.ubuntuone.android.music.ui.dialog.InfoAlertDialog; |
960 | 62 | import com.ubuntuone.android.music.ui.dialog.InputAlertDialog; | 58 | import com.ubuntuone.android.music.ui.dialog.InputAlertDialog; |
961 | 63 | import com.ubuntuone.android.music.ui.dialog.InputAlertDialog.InputAlertDialogListener; | 59 | import com.ubuntuone.android.music.ui.dialog.InputAlertDialog.InputAlertDialogListener; |
962 | 64 | import com.ubuntuone.android.music.ui.dialog.ModalAlertDialog; | 60 | import com.ubuntuone.android.music.ui.dialog.ModalAlertDialog; |
963 | 65 | import com.ubuntuone.api.music.U1MusicAPI; | 61 | import com.ubuntuone.api.music.U1MusicAPI; |
964 | 66 | import com.ubuntuone.api.music.client.Failure; | 62 | import com.ubuntuone.api.music.client.Failure; |
965 | 63 | import com.ubuntuone.api.music.model.U1Playlist; | ||
966 | 67 | import com.ubuntuone.api.music.request.U1PlaylistCreateListener; | 64 | import com.ubuntuone.api.music.request.U1PlaylistCreateListener; |
967 | 65 | import com.ubuntuone.api.music.request.U1PlaylistListener; | ||
968 | 68 | 66 | ||
969 | 69 | public class PlaylistsFragment extends LoadingFragment<U1PlaylistAdapter> implements | 67 | public class PlaylistsFragment extends LoadingFragment<U1PlaylistAdapter> implements |
970 | 70 | OnClickListener, InputAlertDialogListener | 68 | OnClickListener, InputAlertDialogListener |
971 | @@ -74,6 +72,8 @@ | |||
972 | 74 | public static final String EXTRA_INCLUDE_CUSTOM = "include_custom"; | 72 | public static final String EXTRA_INCLUDE_CUSTOM = "include_custom"; |
973 | 75 | 73 | ||
974 | 76 | private boolean mIncludeCustom = false; | 74 | private boolean mIncludeCustom = false; |
975 | 75 | |||
976 | 76 | private OnPlaylistSelectedListener mOnPlaylistSelectedListener; | ||
977 | 77 | 77 | ||
978 | 78 | @Override | 78 | @Override |
979 | 79 | public int onGetHeaderResId() { | 79 | public int onGetHeaderResId() { |
980 | @@ -113,52 +113,18 @@ | |||
981 | 113 | Button createPlaylist = (Button) view.findViewById(R.id.create_playlist); | 113 | Button createPlaylist = (Button) view.findViewById(R.id.create_playlist); |
982 | 114 | createPlaylist.setOnClickListener(this); | 114 | createPlaylist.setOnClickListener(this); |
983 | 115 | 115 | ||
984 | 116 | try { | ||
985 | 117 | mOnPlaylistSelectedListener = (OnPlaylistSelectedListener) getActivity(); | ||
986 | 118 | } catch (ClassCastException e) { | ||
987 | 119 | throw new IllegalArgumentException("Activity must implement OnPlaylistSelectedListener"); | ||
988 | 120 | } | ||
989 | 121 | |||
990 | 116 | return view; | 122 | return view; |
991 | 117 | } | 123 | } |
992 | 118 | 124 | ||
993 | 119 | @Override | 125 | @Override |
994 | 120 | public void onListItemClick(ListView l, View v, int position, long id) { | 126 | public void onListItemClick(ListView l, View v, int position, long id) { |
1036 | 121 | showPlaylistSongs(position); | 127 | mOnPlaylistSelectedListener.onPlaylistSelected(mAdapter, position, mIncludeCustom); |
996 | 122 | } | ||
997 | 123 | |||
998 | 124 | private void showPlaylistSongs(int position) { | ||
999 | 125 | if (mIncludeCustom && position < U1PlaylistAdapter.Position.COUNT) { | ||
1000 | 126 | Context context = getActivity(); | ||
1001 | 127 | switch (position) { | ||
1002 | 128 | case Position.STARRED: { | ||
1003 | 129 | int count = MusicProviderUtils.getStarredSongCount(context); | ||
1004 | 130 | PlaylistActivity.startFrom(context, MusicProviderUtils.STARRED_ID, | ||
1005 | 131 | context.getString(R.string.starred), count); | ||
1006 | 132 | break; | ||
1007 | 133 | } | ||
1008 | 134 | case Position.CACHED: { | ||
1009 | 135 | int count = MusicProviderUtils.getCachedSongCount(context); | ||
1010 | 136 | PlaylistActivity.startFrom(getActivity(), MusicProviderUtils.CACHED_ID, | ||
1011 | 137 | context.getString(R.string.cached), count); | ||
1012 | 138 | break; | ||
1013 | 139 | } | ||
1014 | 140 | case Position.QUEUED: { | ||
1015 | 141 | PlayerActivity.startWithQueue(getSherlockActivity()); | ||
1016 | 142 | break; | ||
1017 | 143 | } | ||
1018 | 144 | } | ||
1019 | 145 | } else { | ||
1020 | 146 | if (mIncludeCustom) position -= Position.COUNT; | ||
1021 | 147 | |||
1022 | 148 | Cursor cursor = mAdapter.getCursor(); | ||
1023 | 149 | cursor.moveToPosition(position); | ||
1024 | 150 | |||
1025 | 151 | int songCount = cursor.getInt(cursor.getColumnIndex(Playlists.PLAYLIST_SONG_COUNT)); | ||
1026 | 152 | if (songCount == 0) { | ||
1027 | 153 | String title = cursor.getString(cursor.getColumnIndex(Playlists.PLAYLIST_NAME)); | ||
1028 | 154 | String text = getString(R.string.playlist_is_empty, title); | ||
1029 | 155 | if (isResumed()) { | ||
1030 | 156 | Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show(); | ||
1031 | 157 | } | ||
1032 | 158 | } else { | ||
1033 | 159 | PlaylistActivity.startFrom(getActivity(), cursor); | ||
1034 | 160 | } | ||
1035 | 161 | } | ||
1037 | 162 | } | 128 | } |
1038 | 163 | 129 | ||
1039 | 164 | @Override | 130 | @Override |
1040 | @@ -238,6 +204,7 @@ | |||
1041 | 238 | api.createPlaylist(name, emptyList, new U1PlaylistCreateListener() { | 204 | api.createPlaylist(name, emptyList, new U1PlaylistCreateListener() { |
1042 | 239 | @Override | 205 | @Override |
1043 | 240 | public void onSuccess(String playlistId) { | 206 | public void onSuccess(String playlistId) { |
1044 | 207 | // TODO Persist playlist once CSRF fix is rolled out. | ||
1045 | 241 | Log.i(TAG, "Created playlist with id: " + playlistId); | 208 | Log.i(TAG, "Created playlist with id: " + playlistId); |
1046 | 242 | mPlaylistId = playlistId; | 209 | mPlaylistId = playlistId; |
1047 | 243 | } | 210 | } |
1048 | @@ -250,85 +217,40 @@ | |||
1049 | 250 | } | 217 | } |
1050 | 251 | }); | 218 | }); |
1051 | 252 | 219 | ||
1053 | 253 | // TODO karni: save the playlist | 220 | // TODO This block will be removed soon, see TODO above. |
1054 | 221 | Activity activity = getSherlockActivity(); | ||
1055 | 222 | final ContentResolver resolver = activity != null ? activity.getContentResolver() : null; | ||
1056 | 223 | if (mPlaylistId != null && resolver != null) { | ||
1057 | 224 | api.getPlaylists(new U1PlaylistListener() { | ||
1058 | 225 | @Override | ||
1059 | 226 | public void onSuccess(U1Playlist playlist) { | ||
1060 | 227 | if (mPlaylistId.equals(playlist.getId())) { | ||
1061 | 228 | new PlaylistDao().updateOrInsert(resolver, playlist); | ||
1062 | 229 | } | ||
1063 | 230 | } | ||
1064 | 231 | }); | ||
1065 | 232 | } | ||
1066 | 233 | |||
1067 | 254 | return mPlaylistId != null; | 234 | return mPlaylistId != null; |
1068 | 255 | } | 235 | } |
1069 | 256 | 236 | ||
1070 | 257 | @Override | 237 | @Override |
1072 | 258 | protected void onPostExecute(Boolean result) { | 238 | protected void onPostExecute(Boolean created) { |
1073 | 259 | if (mDialogFragment != null && mDialogFragment.isAdded()) { | 239 | if (mDialogFragment != null && mDialogFragment.isAdded()) { |
1074 | 260 | mDialogFragment.dismiss(); | 240 | mDialogFragment.dismiss(); |
1075 | 261 | } | 241 | } |
1076 | 262 | 242 | ||
1077 | 263 | SherlockFragmentActivity activity = getSherlockActivity(); | 243 | SherlockFragmentActivity activity = getSherlockActivity(); |
1078 | 264 | boolean created = mPlaylistId != null; | ||
1079 | 265 | if (created && activity != null) { | 244 | if (created && activity != null) { |
1080 | 266 | ((HomeActivity) activity).forcePlaylistsRefresh(); | 245 | ((HomeActivity) activity).forcePlaylistsRefresh(); |
1081 | 267 | } else if (!created && activity != null && !TextUtils.isEmpty(mErrorMessage)) { | 246 | } else if (!created && activity != null && !TextUtils.isEmpty(mErrorMessage)) { |
1084 | 268 | DialogFragment frag = InfoAlertDialog.newInstance(INFO_DIALOG_ID, | 247 | DialogFragment frag = InfoAlertDialog.newInstance(ERROR_DIALOG_ID, 0, mErrorMessage); |
1083 | 269 | R.string.creating_playlist_failed_title, mErrorMessage); | ||
1085 | 270 | frag.show(activity.getSupportFragmentManager(), null); | 248 | frag.show(activity.getSupportFragmentManager(), null); |
1086 | 271 | } | 249 | } |
1087 | 272 | } | 250 | } |
1088 | 273 | } | 251 | } |
1089 | 274 | 252 | ||
1148 | 275 | private class AppendToPlaylistTask extends AsyncTask<Uri, Void, Boolean> { | 253 | public interface OnPlaylistSelectedListener { |
1149 | 276 | private DialogFragment mDialogFragment; | 254 | public void onPlaylistSelected(Adapter adapter, int position, boolean hasHeaders); |
1092 | 277 | private Boolean mUpdated = false; | ||
1093 | 278 | private String mErrorMessage; | ||
1094 | 279 | |||
1095 | 280 | @Override | ||
1096 | 281 | protected void onPreExecute() { | ||
1097 | 282 | SherlockFragmentActivity activity = getSherlockActivity(); | ||
1098 | 283 | if (activity != null) { | ||
1099 | 284 | mDialogFragment = ModalAlertDialog.newInstance(); | ||
1100 | 285 | mDialogFragment.show(activity.getSupportFragmentManager(), "pleaseWaitDialog"); | ||
1101 | 286 | } | ||
1102 | 287 | } | ||
1103 | 288 | |||
1104 | 289 | @Override | ||
1105 | 290 | protected Boolean doInBackground(Uri... params) { | ||
1106 | 291 | if (params.length != 1) { | ||
1107 | 292 | throw new IllegalArgumentException( | ||
1108 | 293 | "AppendToPlaylistTask takes two arguments, playlist uri and content uri"); | ||
1109 | 294 | } | ||
1110 | 295 | final Uri playlistUri = params[0]; | ||
1111 | 296 | final Uri contentUri = params[1]; | ||
1112 | 297 | |||
1113 | 298 | Activity activity = getSherlockActivity(); | ||
1114 | 299 | ContentResolver resolver = activity != null ? activity.getContentResolver() : null; | ||
1115 | 300 | if (resolver == null) return mUpdated; | ||
1116 | 301 | |||
1117 | 302 | String mimeType = resolver.getType(contentUri); | ||
1118 | 303 | if (mimeType.equals(Artists.CONTENT_ITEM_TYPE)) { | ||
1119 | 304 | MusicProviderUtils.enqueueArtist(activity, contentUri, playlistUri); | ||
1120 | 305 | } else if (mimeType.equals(Albums.CONTENT_ITEM_TYPE)) { | ||
1121 | 306 | MusicProviderUtils.enqueueAlbum(activity, contentUri, playlistUri); | ||
1122 | 307 | } else if (mimeType.equals(Songs.CONTENT_ITEM_TYPE)) { | ||
1123 | 308 | MusicProviderUtils.enqueueSong(activity, contentUri, playlistUri); | ||
1124 | 309 | } else { | ||
1125 | 310 | Log.e(TAG, "Unknown content uri to enqueue to playlist: " + contentUri.toString()); | ||
1126 | 311 | } | ||
1127 | 312 | |||
1128 | 313 | U1MusicAPI api = UbuntuOneMusic.getInstance().getMusicApi(); | ||
1129 | 314 | // TODO save playlist to server | ||
1130 | 315 | return mUpdated; | ||
1131 | 316 | } | ||
1132 | 317 | |||
1133 | 318 | @Override | ||
1134 | 319 | protected void onPostExecute(Boolean result) { | ||
1135 | 320 | if (mDialogFragment != null && mDialogFragment.isAdded()) { | ||
1136 | 321 | mDialogFragment.dismiss(); | ||
1137 | 322 | } | ||
1138 | 323 | |||
1139 | 324 | SherlockFragmentActivity activity = getSherlockActivity(); | ||
1140 | 325 | if (mUpdated && activity != null) { | ||
1141 | 326 | ((HomeActivity) activity).forcePlaylistsRefresh(); | ||
1142 | 327 | } else if (!mUpdated && activity != null && !TextUtils.isEmpty(mErrorMessage)) { | ||
1143 | 328 | DialogFragment frag = InfoAlertDialog.newInstance(INFO_DIALOG_ID, | ||
1144 | 329 | R.string.creating_playlist_failed_title, mErrorMessage); | ||
1145 | 330 | frag.show(activity.getSupportFragmentManager(), null); | ||
1146 | 331 | } | ||
1147 | 332 | } | ||
1150 | 333 | } | 255 | } |
1151 | 334 | } | 256 | } |
1152 | 335 | 257 | ||
1153 | === modified file 'src/com/ubuntuone/android/music/ui/SongsFragment.java' | |||
1154 | --- src/com/ubuntuone/android/music/ui/SongsFragment.java 2012-11-08 14:14:54 +0000 | |||
1155 | +++ src/com/ubuntuone/android/music/ui/SongsFragment.java 2012-11-28 17:49:20 +0000 | |||
1156 | @@ -26,7 +26,9 @@ | |||
1157 | 26 | import static com.ubuntuone.android.music.ui.PlaylistActivity.EXTRA_PLAYLIST_ID; | 26 | import static com.ubuntuone.android.music.ui.PlaylistActivity.EXTRA_PLAYLIST_ID; |
1158 | 27 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; | 27 | import static com.ubuntuone.android.music.util.LogUtils.makeLogTag; |
1159 | 28 | import android.app.Activity; | 28 | import android.app.Activity; |
1160 | 29 | import android.content.ContentResolver; | ||
1161 | 29 | import android.content.Context; | 30 | import android.content.Context; |
1162 | 31 | import android.content.Intent; | ||
1163 | 30 | import android.database.Cursor; | 32 | import android.database.Cursor; |
1164 | 31 | import android.net.Uri; | 33 | import android.net.Uri; |
1165 | 32 | import android.os.Bundle; | 34 | import android.os.Bundle; |
1166 | @@ -49,9 +51,11 @@ | |||
1167 | 49 | import com.ubuntuone.android.music.adapter.U1SongAdapter; | 51 | import com.ubuntuone.android.music.adapter.U1SongAdapter; |
1168 | 50 | import com.ubuntuone.android.music.provider.MusicContract.Albums; | 52 | import com.ubuntuone.android.music.provider.MusicContract.Albums; |
1169 | 51 | import com.ubuntuone.android.music.provider.MusicContract.Genres; | 53 | import com.ubuntuone.android.music.provider.MusicContract.Genres; |
1170 | 54 | import com.ubuntuone.android.music.provider.MusicContract.PlaylistSongs; | ||
1171 | 52 | import com.ubuntuone.android.music.provider.MusicContract.Playlists; | 55 | import com.ubuntuone.android.music.provider.MusicContract.Playlists; |
1172 | 53 | import com.ubuntuone.android.music.provider.MusicContract.Songs; | 56 | import com.ubuntuone.android.music.provider.MusicContract.Songs; |
1173 | 54 | import com.ubuntuone.android.music.provider.MusicProviderUtils; | 57 | import com.ubuntuone.android.music.provider.MusicProviderUtils; |
1174 | 58 | import com.ubuntuone.android.music.service.SyncService; | ||
1175 | 55 | import com.ubuntuone.android.music.util.UIUtils; | 59 | import com.ubuntuone.android.music.util.UIUtils; |
1176 | 56 | 60 | ||
1177 | 57 | public class SongsFragment extends LoadingFragment<U1SongAdapter> implements OnClickListener | 61 | public class SongsFragment extends LoadingFragment<U1SongAdapter> implements OnClickListener |
1178 | @@ -129,28 +133,28 @@ | |||
1179 | 129 | if (mAlbumId != null) { | 133 | if (mAlbumId != null) { |
1180 | 130 | Uri albumSongsUri = Albums.buildSongsUri(mAlbumId); | 134 | Uri albumSongsUri = Albums.buildSongsUri(mAlbumId); |
1181 | 131 | loader = new CursorLoader(getSherlockActivity(), albumSongsUri, | 135 | loader = new CursorLoader(getSherlockActivity(), albumSongsUri, |
1183 | 132 | Songs.DEFAULT_PROJECTION, null, null, Songs.DEFAULT_SORT); | 136 | Songs.getDefaultProjection(), null, null, Albums.DEFAULT_SONG_SORT); |
1184 | 133 | } else if (mPlaylistId != null) { | 137 | } else if (mPlaylistId != null) { |
1185 | 134 | if (mPlaylistId.equals(MusicProviderUtils.STARRED_ID)) { | 138 | if (mPlaylistId.equals(MusicProviderUtils.STARRED_ID)) { |
1186 | 135 | loader = new CursorLoader(getSherlockActivity(), Songs.STARRED_SONGS_URI, | 139 | loader = new CursorLoader(getSherlockActivity(), Songs.STARRED_SONGS_URI, |
1188 | 136 | Songs.DEFAULT_PROJECTION, null, null, Songs.DEFAULT_SORT); | 140 | Songs.getDefaultProjection(), null, null, Songs.DEFAULT_SORT); |
1189 | 137 | loader.onContentChanged(); | 141 | loader.onContentChanged(); |
1190 | 138 | } else if (mPlaylistId.equals(MusicProviderUtils.CACHED_ID)) { | 142 | } else if (mPlaylistId.equals(MusicProviderUtils.CACHED_ID)) { |
1191 | 139 | loader = new CursorLoader(getSherlockActivity(), Songs.CACHED_SONGS_URI, | 143 | loader = new CursorLoader(getSherlockActivity(), Songs.CACHED_SONGS_URI, |
1193 | 140 | Songs.DEFAULT_PROJECTION, null, null, Songs.DEFAULT_SORT); | 144 | Songs.getDefaultProjection(), null, null, Songs.DEFAULT_SORT); |
1194 | 141 | loader.onContentChanged(); | 145 | loader.onContentChanged(); |
1195 | 142 | } else { | 146 | } else { |
1196 | 143 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri(mPlaylistId); | 147 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri(mPlaylistId); |
1197 | 144 | loader = new CursorLoader(getSherlockActivity(), playlistSongsUri, | 148 | loader = new CursorLoader(getSherlockActivity(), playlistSongsUri, |
1199 | 145 | Songs.DEFAULT_PROJECTION, null, null, Songs.DEFAULT_SORT); | 149 | PlaylistSongs.DEFAULT_PROJECTION.clone(), null, null, PlaylistSongs.DEFAULT_SORT); |
1200 | 146 | } | 150 | } |
1201 | 147 | } else if (mGenreId != null) { | 151 | } else if (mGenreId != null) { |
1202 | 148 | Uri genreSongsUri = Genres.buildGenreSongsUri(mGenreId); | 152 | Uri genreSongsUri = Genres.buildGenreSongsUri(mGenreId); |
1203 | 149 | loader = new CursorLoader(getSherlockActivity(), genreSongsUri, | 153 | loader = new CursorLoader(getSherlockActivity(), genreSongsUri, |
1205 | 150 | Songs.DEFAULT_PROJECTION, null, null, Songs.DEFAULT_SORT); | 154 | Songs.getDefaultProjection(), null, null, Songs.DEFAULT_SORT); |
1206 | 151 | } else { | 155 | } else { |
1207 | 152 | loader = new CursorLoader(getSherlockActivity(), Songs.CONTENT_URI, | 156 | loader = new CursorLoader(getSherlockActivity(), Songs.CONTENT_URI, |
1209 | 153 | Songs.DEFAULT_PROJECTION, null, null, Songs.DEFAULT_SORT); | 157 | Songs.getDefaultProjection(), null, null, Songs.DEFAULT_SORT); |
1210 | 154 | } | 158 | } |
1211 | 155 | setIsLoading(true); | 159 | setIsLoading(true); |
1212 | 156 | return loader; | 160 | return loader; |
1213 | @@ -189,15 +193,18 @@ | |||
1214 | 189 | @Override | 193 | @Override |
1215 | 190 | public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { | 194 | public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { |
1216 | 191 | if (v.getId() == android.R.id.list) { | 195 | if (v.getId() == android.R.id.list) { |
1224 | 192 | menu.add(Menu.NONE, R.id.context_play, 0, R.string.description_play); | 196 | menu.add(Menu.NONE, R.id.context_play, 0, |
1225 | 193 | 197 | R.string.description_play); | |
1226 | 194 | menu.add(Menu.NONE, R.id.context_star, 0, R.string.description_star); | 198 | menu.add(Menu.NONE, R.id.context_star, 0, |
1227 | 195 | Activity activity = getSherlockActivity(); | 199 | R.string.description_star); |
1228 | 196 | if (activity != null && UIUtils.isNetworkConnected(activity)) { | 200 | menu.add(Menu.NONE, R.id.context_add_to_playlist, 0, |
1229 | 197 | menu.add(Menu.NONE, R.id.context_add_to_playlist, 0, | 201 | R.string.description_add_to_playlist); |
1230 | 198 | R.string.description_add_to_playlist); | 202 | if (mPlaylistId != null) { |
1231 | 203 | menu.add(Menu.NONE, R.id.context_remove_from_playlist, 0, | ||
1232 | 204 | R.string.description_remove_from_playlist); | ||
1233 | 199 | } | 205 | } |
1235 | 200 | menu.add(Menu.NONE, R.id.context_add_to_queue, 0, R.string.description_add_to_queue); | 206 | menu.add(Menu.NONE, R.id.context_add_to_queue, 0, |
1236 | 207 | R.string.description_add_to_queue); | ||
1237 | 201 | } else { | 208 | } else { |
1238 | 202 | super.onCreateContextMenu(menu, v, menuInfo); | 209 | super.onCreateContextMenu(menu, v, menuInfo); |
1239 | 203 | } | 210 | } |
1240 | @@ -216,6 +223,8 @@ | |||
1241 | 216 | return onStarContextItemSelected(position); | 223 | return onStarContextItemSelected(position); |
1242 | 217 | case R.id.context_add_to_playlist: | 224 | case R.id.context_add_to_playlist: |
1243 | 218 | return onAddToPlaylistContextItemSelected(position); | 225 | return onAddToPlaylistContextItemSelected(position); |
1244 | 226 | case R.id.context_remove_from_playlist: | ||
1245 | 227 | return onRemoveFromPlaylistContextItemSelected(position); | ||
1246 | 219 | case R.id.context_add_to_queue: | 228 | case R.id.context_add_to_queue: |
1247 | 220 | return onAddToPlayQueueContextItemSelected(position); | 229 | return onAddToPlayQueueContextItemSelected(position); |
1248 | 221 | default: | 230 | default: |
1249 | @@ -223,6 +232,12 @@ | |||
1250 | 223 | } | 232 | } |
1251 | 224 | } | 233 | } |
1252 | 225 | 234 | ||
1253 | 235 | private void forceReload() { | ||
1254 | 236 | int loaderId = getLoaderId(); | ||
1255 | 237 | LoaderManager lm = getSherlockActivity().getSupportLoaderManager(); | ||
1256 | 238 | lm.getLoader(loaderId).forceLoad(); | ||
1257 | 239 | } | ||
1258 | 240 | |||
1259 | 226 | private boolean onPlayContextItemSelected(int position) { | 241 | private boolean onPlayContextItemSelected(int position) { |
1260 | 227 | clearQueueAndPlay(mListView, position); | 242 | clearQueueAndPlay(mListView, position); |
1261 | 228 | return true; | 243 | return true; |
1262 | @@ -238,16 +253,41 @@ | |||
1263 | 238 | 253 | ||
1264 | 239 | MusicProviderUtils.toggleSongStarred(context, songUri); | 254 | MusicProviderUtils.toggleSongStarred(context, songUri); |
1265 | 240 | 255 | ||
1269 | 241 | int loaderId = getLoaderId(); | 256 | forceReload(); |
1267 | 242 | LoaderManager lm = getSherlockActivity().getSupportLoaderManager(); | ||
1268 | 243 | lm.getLoader(loaderId).forceLoad(); | ||
1270 | 244 | } | 257 | } |
1271 | 245 | } | 258 | } |
1272 | 246 | return true; | 259 | return true; |
1273 | 247 | } | 260 | } |
1274 | 248 | 261 | ||
1275 | 249 | private boolean onAddToPlaylistContextItemSelected(int position) { | 262 | private boolean onAddToPlaylistContextItemSelected(int position) { |
1277 | 250 | // TODO | 263 | Cursor cursor = (Cursor) mListView.getItemAtPosition(position); |
1278 | 264 | String songId = cursor.getString(cursor.getColumnIndex(Songs.SONG_ID)); | ||
1279 | 265 | Uri songUri = Songs.buildSongUri(songId); | ||
1280 | 266 | |||
1281 | 267 | Intent intent = new Intent(getActivity(), PlaylistsActivity.class); | ||
1282 | 268 | intent.putExtra(PlaylistsActivity.EXTRA_ENQUEUE_CONTENT_ID, songUri); | ||
1283 | 269 | startActivity(intent); | ||
1284 | 270 | return true; | ||
1285 | 271 | } | ||
1286 | 272 | |||
1287 | 273 | private boolean onRemoveFromPlaylistContextItemSelected(int position) { | ||
1288 | 274 | Cursor cursor = (Cursor) mListView.getItemAtPosition(position); | ||
1289 | 275 | String rowId = cursor.getString(cursor.getColumnIndex(Songs._ID)); | ||
1290 | 276 | |||
1291 | 277 | ContentResolver resolver = getActivity().getContentResolver(); | ||
1292 | 278 | String selection = Songs._ID + "=?"; | ||
1293 | 279 | String[] selectionArgs = new String[] { rowId }; | ||
1294 | 280 | resolver.delete(PlaylistSongs.CONTENT_URI, selection, selectionArgs); | ||
1295 | 281 | |||
1296 | 282 | Activity activity = getActivity(); | ||
1297 | 283 | Uri playlistUri = Playlists.buildPlaylistUri(mPlaylistId); | ||
1298 | 284 | MusicProviderUtils.flagPlaylistForSync(activity, playlistUri, true); | ||
1299 | 285 | |||
1300 | 286 | forceReload(); | ||
1301 | 287 | if (activity != null && UIUtils.isNetworkConnected(activity)) { | ||
1302 | 288 | Intent syncPlaylists = new Intent(SyncService.ACTION_SYNC_PLAYLISTS); | ||
1303 | 289 | activity.startService(syncPlaylists); | ||
1304 | 290 | } | ||
1305 | 251 | return true; | 291 | return true; |
1306 | 252 | } | 292 | } |
1307 | 253 | 293 | ||
1308 | 254 | 294 | ||
1309 | === modified file 'src/com/ubuntuone/android/music/ui/dialog/InfoAlertDialog.java' | |||
1310 | --- src/com/ubuntuone/android/music/ui/dialog/InfoAlertDialog.java 2012-11-08 14:14:54 +0000 | |||
1311 | +++ src/com/ubuntuone/android/music/ui/dialog/InfoAlertDialog.java 2012-11-28 17:49:20 +0000 | |||
1312 | @@ -28,6 +28,7 @@ | |||
1313 | 28 | import android.content.DialogInterface.OnClickListener; | 28 | import android.content.DialogInterface.OnClickListener; |
1314 | 29 | import android.os.Bundle; | 29 | import android.os.Bundle; |
1315 | 30 | import android.view.Gravity; | 30 | import android.view.Gravity; |
1316 | 31 | import android.view.ViewGroup.LayoutParams; | ||
1317 | 31 | import android.widget.TextView; | 32 | import android.widget.TextView; |
1318 | 32 | 33 | ||
1319 | 33 | import com.actionbarsherlock.app.SherlockDialogFragment; | 34 | import com.actionbarsherlock.app.SherlockDialogFragment; |
1320 | @@ -41,7 +42,7 @@ | |||
1321 | 41 | InfoAlertDialog frag = new InfoAlertDialog(); | 42 | InfoAlertDialog frag = new InfoAlertDialog(); |
1322 | 42 | Bundle args = new Bundle(); | 43 | Bundle args = new Bundle(); |
1323 | 43 | args.putInt("dialogId", dialogId); | 44 | args.putInt("dialogId", dialogId); |
1325 | 44 | args.putInt("titleId", titleId); | 45 | if (titleId != 0) args.putInt("titleId", titleId); |
1326 | 45 | args.putString("message", message); | 46 | args.putString("message", message); |
1327 | 46 | frag.setArguments(args); | 47 | frag.setArguments(args); |
1328 | 47 | return frag; | 48 | return frag; |
1329 | @@ -61,11 +62,12 @@ | |||
1330 | 61 | public Dialog onCreateDialog(Bundle savedInstanceState) { | 62 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
1331 | 62 | Bundle args = getArguments(); | 63 | Bundle args = getArguments(); |
1332 | 63 | final int dialogId = args.getInt("dialogId"); | 64 | final int dialogId = args.getInt("dialogId"); |
1333 | 64 | final int titleId = args.getInt("titleId"); | ||
1334 | 65 | final String message = args.getString("message"); | 65 | final String message = args.getString("message"); |
1335 | 66 | 66 | ||
1336 | 67 | final TextView view = new TextView(getSherlockActivity()); | 67 | final TextView view = new TextView(getSherlockActivity()); |
1337 | 68 | view.setTextAppearance(getSherlockActivity(), android.R.style.TextAppearance_Large); | ||
1338 | 68 | view.setGravity(Gravity.CENTER); | 69 | view.setGravity(Gravity.CENTER); |
1339 | 70 | view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT)); | ||
1340 | 69 | view.setText(message); | 71 | view.setText(message); |
1341 | 70 | 72 | ||
1342 | 71 | OnClickListener listener = new OnClickListener() { | 73 | OnClickListener listener = new OnClickListener() { |
1343 | @@ -79,11 +81,15 @@ | |||
1344 | 79 | } | 81 | } |
1345 | 80 | }; | 82 | }; |
1346 | 81 | 83 | ||
1349 | 82 | return new AlertDialog.Builder(getActivity()) | 84 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) |
1348 | 83 | .setTitle(titleId) | ||
1350 | 84 | .setView(view) | 85 | .setView(view) |
1353 | 85 | .setPositiveButton(R.string.ok, listener) | 86 | .setPositiveButton(R.string.ok, listener); |
1354 | 86 | .create(); | 87 | if (args.containsKey("titleId")) { |
1355 | 88 | int titleId = args.getInt("titleId"); | ||
1356 | 89 | builder.setTitle(titleId); | ||
1357 | 90 | } | ||
1358 | 91 | |||
1359 | 92 | return builder.create(); | ||
1360 | 87 | } | 93 | } |
1361 | 88 | 94 | ||
1362 | 89 | public static interface InfoAlertDialogListener { | 95 | public static interface InfoAlertDialogListener { |
1363 | 90 | 96 | ||
1364 | === modified file 'test/src/com/ubuntuone/android/music/provider/MusicProviderInsertTest.java' | |||
1365 | --- test/src/com/ubuntuone/android/music/provider/MusicProviderInsertTest.java 2012-11-22 11:17:42 +0000 | |||
1366 | +++ test/src/com/ubuntuone/android/music/provider/MusicProviderInsertTest.java 2012-11-28 17:49:20 +0000 | |||
1367 | @@ -161,7 +161,7 @@ | |||
1368 | 161 | 161 | ||
1369 | 162 | assertNotNull("Inserted song uri is null.", uri); | 162 | assertNotNull("Inserted song uri is null.", uri); |
1370 | 163 | 163 | ||
1372 | 164 | Cursor cursor = mResolver.query(uri, Songs.DEFAULT_PROJECTION, null, null, null); | 164 | Cursor cursor = mResolver.query(uri, Songs.getDefaultProjection(), null, null, null); |
1373 | 165 | assertEquals("Wrong song row count returned.", 1, cursor.getCount()); | 165 | assertEquals("Wrong song row count returned.", 1, cursor.getCount()); |
1374 | 166 | assertTrue("Cursor missing rows.", cursor.moveToNext()); | 166 | assertTrue("Cursor missing rows.", cursor.moveToNext()); |
1375 | 167 | 167 | ||
1376 | @@ -218,7 +218,7 @@ | |||
1377 | 218 | 218 | ||
1378 | 219 | Uri uri = Songs.buildSongUri(song.getId()); | 219 | Uri uri = Songs.buildSongUri(song.getId()); |
1379 | 220 | 220 | ||
1381 | 221 | Cursor cursor = mResolver.query(uri, Songs.DEFAULT_PROJECTION, null, null, null); | 221 | Cursor cursor = mResolver.query(uri, Songs.getDefaultProjection(), null, null, null); |
1382 | 222 | assertEquals("Wrong song row count returned.", 1, cursor.getCount()); | 222 | assertEquals("Wrong song row count returned.", 1, cursor.getCount()); |
1383 | 223 | assertTrue("Cursor missing rows.", cursor.moveToNext()); | 223 | assertTrue("Cursor missing rows.", cursor.moveToNext()); |
1384 | 224 | 224 | ||
1385 | 225 | 225 | ||
1386 | === modified file 'test/src/com/ubuntuone/android/music/provider/MusicProviderQueryTest.java' | |||
1387 | --- test/src/com/ubuntuone/android/music/provider/MusicProviderQueryTest.java 2012-11-08 14:14:54 +0000 | |||
1388 | +++ test/src/com/ubuntuone/android/music/provider/MusicProviderQueryTest.java 2012-11-28 17:49:20 +0000 | |||
1389 | @@ -81,7 +81,7 @@ | |||
1390 | 81 | public void testQueryArtistSongs() { | 81 | public void testQueryArtistSongs() { |
1391 | 82 | Uri artistSongsUri = Artists.buildSongsUri(HashUtils.md5("artist1-artist_name")); | 82 | Uri artistSongsUri = Artists.buildSongsUri(HashUtils.md5("artist1-artist_name")); |
1392 | 83 | Cursor cursor = mResolver.query(artistSongsUri, | 83 | Cursor cursor = mResolver.query(artistSongsUri, |
1394 | 84 | Songs.DEFAULT_PROJECTION, null, null, Songs.DEFAULT_SORT); | 84 | Songs.getDefaultProjection(), null, null, Songs.DEFAULT_SORT); |
1395 | 85 | 85 | ||
1396 | 86 | assertEquals("Wrong artist songs count returned.", 2, cursor.getCount()); | 86 | assertEquals("Wrong artist songs count returned.", 2, cursor.getCount()); |
1397 | 87 | 87 | ||
1398 | @@ -141,7 +141,7 @@ | |||
1399 | 141 | Uri albumSongsUri = Albums.buildSongsUri( | 141 | Uri albumSongsUri = Albums.buildSongsUri( |
1400 | 142 | HashUtils.md5("album1-album_titleartist1-artist_name")); | 142 | HashUtils.md5("album1-album_titleartist1-artist_name")); |
1401 | 143 | Cursor cursor = mResolver.query(albumSongsUri, | 143 | Cursor cursor = mResolver.query(albumSongsUri, |
1403 | 144 | Songs.DEFAULT_PROJECTION, null, null, Songs.DEFAULT_SORT); | 144 | Songs.getDefaultProjection(), null, null, Songs.DEFAULT_SORT); |
1404 | 145 | 145 | ||
1405 | 146 | assertEquals("Wrong album songs count returned.", 2, cursor.getCount()); | 146 | assertEquals("Wrong album songs count returned.", 2, cursor.getCount()); |
1406 | 147 | 147 | ||
1407 | @@ -156,7 +156,7 @@ | |||
1408 | 156 | 156 | ||
1409 | 157 | public void testQuerySongs() { | 157 | public void testQuerySongs() { |
1410 | 158 | Cursor cursor = mResolver.query(Songs.CONTENT_URI, | 158 | Cursor cursor = mResolver.query(Songs.CONTENT_URI, |
1412 | 159 | Songs.DEFAULT_PROJECTION, null, null, Songs.DEFAULT_SORT); | 159 | Songs.getDefaultProjection(), null, null, Songs.DEFAULT_SORT); |
1413 | 160 | 160 | ||
1414 | 161 | assertEquals("Wrong song count returned.", MockData.SONGS_COUNT, cursor.getCount()); | 161 | assertEquals("Wrong song count returned.", MockData.SONGS_COUNT, cursor.getCount()); |
1415 | 162 | 162 | ||
1416 | @@ -173,7 +173,7 @@ | |||
1417 | 173 | public void testQuerySongsId() { | 173 | public void testQuerySongsId() { |
1418 | 174 | Uri songUri = Songs.buildSongUri("song1-song_id"); | 174 | Uri songUri = Songs.buildSongUri("song1-song_id"); |
1419 | 175 | Cursor cursor = mResolver.query(songUri, | 175 | Cursor cursor = mResolver.query(songUri, |
1421 | 176 | Songs.DEFAULT_PROJECTION, null, null, null); | 176 | Songs.getDefaultProjection(), null, null, null); |
1422 | 177 | 177 | ||
1423 | 178 | assertEquals("Wrong songs count returned.", | 178 | assertEquals("Wrong songs count returned.", |
1424 | 179 | 1, cursor.getCount()); | 179 | 1, cursor.getCount()); |
1425 | 180 | 180 | ||
1426 | === modified file 'test/src/com/ubuntuone/android/music/provider/MusicProviderUtilsTest.java' | |||
1427 | --- test/src/com/ubuntuone/android/music/provider/MusicProviderUtilsTest.java 2012-11-13 13:58:31 +0000 | |||
1428 | +++ test/src/com/ubuntuone/android/music/provider/MusicProviderUtilsTest.java 2012-11-28 17:49:20 +0000 | |||
1429 | @@ -113,7 +113,7 @@ | |||
1430 | 113 | } | 113 | } |
1431 | 114 | 114 | ||
1432 | 115 | public void testGetPlaylistSongCount() { | 115 | public void testGetPlaylistSongCount() { |
1434 | 116 | Uri playlistUri = Playlists.buildPlaylistSongsUri("playlist1-playlist_id"); | 116 | Uri playlistUri = Playlists.buildPlaylistUri("playlist1-playlist_id"); |
1435 | 117 | int songCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); | 117 | int songCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); |
1436 | 118 | assertEquals("Wrong playlist song count.", 2, songCount); | 118 | assertEquals("Wrong playlist song count.", 2, songCount); |
1437 | 119 | } | 119 | } |
1438 | @@ -181,7 +181,7 @@ | |||
1439 | 181 | } | 181 | } |
1440 | 182 | 182 | ||
1441 | 183 | public void testEnqueueSongInPlaylist() { | 183 | public void testEnqueueSongInPlaylist() { |
1443 | 184 | Uri playlistUri = Playlists.buildPlaylistSongsUri("playlist2-playlist_id"); | 184 | Uri playlistUri = Playlists.buildPlaylistUri("playlist2-playlist_id"); |
1444 | 185 | int songCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); | 185 | int songCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); |
1445 | 186 | assertEquals("Wrong song count of playlist.", 1, songCount); | 186 | assertEquals("Wrong song count of playlist.", 1, songCount); |
1446 | 187 | 187 | ||
1447 | @@ -192,10 +192,11 @@ | |||
1448 | 192 | int newSongCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); | 192 | int newSongCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); |
1449 | 193 | assertEquals("Wrong new song count of playlist.", songCount + 1, newSongCount); | 193 | assertEquals("Wrong new song count of playlist.", songCount + 1, newSongCount); |
1450 | 194 | 194 | ||
1451 | 195 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri("playlist2-playlist_id"); | ||
1452 | 195 | Cursor cursor = null; | 196 | Cursor cursor = null; |
1453 | 196 | try { | 197 | try { |
1454 | 197 | String[] projection = new String[] { Songs.SONG_ID }; | 198 | String[] projection = new String[] { Songs.SONG_ID }; |
1456 | 198 | cursor = mResolver.query(playlistUri, projection, | 199 | cursor = mResolver.query(playlistSongsUri, projection, |
1457 | 199 | null, null, PlaylistSongs.DEFAULT_SORT); | 200 | null, null, PlaylistSongs.DEFAULT_SORT); |
1458 | 200 | if (cursor != null && cursor.isBeforeFirst()) { | 201 | if (cursor != null && cursor.isBeforeFirst()) { |
1459 | 201 | cursor.moveToLast(); | 202 | cursor.moveToLast(); |
1460 | @@ -232,7 +233,7 @@ | |||
1461 | 232 | } | 233 | } |
1462 | 233 | 234 | ||
1463 | 234 | public void testEnqueueAlbumInPlaylist() { | 235 | public void testEnqueueAlbumInPlaylist() { |
1465 | 235 | Uri playlistUri = Playlists.buildPlaylistSongsUri("playlist2-playlist_id"); | 236 | Uri playlistUri = Playlists.buildPlaylistUri("playlist2-playlist_id"); |
1466 | 236 | int songCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); | 237 | int songCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); |
1467 | 237 | assertEquals("Wrong song count of playlist.", 1, songCount); | 238 | assertEquals("Wrong song count of playlist.", 1, songCount); |
1468 | 238 | 239 | ||
1469 | @@ -244,10 +245,11 @@ | |||
1470 | 244 | int newSongCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); | 245 | int newSongCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); |
1471 | 245 | assertEquals("Wrong new song count of playlist.", songCount + albumSongCount, newSongCount); | 246 | assertEquals("Wrong new song count of playlist.", songCount + albumSongCount, newSongCount); |
1472 | 246 | 247 | ||
1473 | 248 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri("playlist2-playlist_id"); | ||
1474 | 247 | Cursor cursor = null; | 249 | Cursor cursor = null; |
1475 | 248 | try { | 250 | try { |
1476 | 249 | String[] projection = new String[] { Songs.SONG_ID }; | 251 | String[] projection = new String[] { Songs.SONG_ID }; |
1478 | 250 | cursor = mResolver.query(playlistUri, projection, | 252 | cursor = mResolver.query(playlistSongsUri, projection, |
1479 | 251 | null, null, PlaylistSongs.DEFAULT_SORT); | 253 | null, null, PlaylistSongs.DEFAULT_SORT); |
1480 | 252 | if (cursor != null && cursor.isBeforeFirst()) { | 254 | if (cursor != null && cursor.isBeforeFirst()) { |
1481 | 253 | cursor.moveToFirst(); | 255 | cursor.moveToFirst(); |
1482 | @@ -298,7 +300,7 @@ | |||
1483 | 298 | } | 300 | } |
1484 | 299 | 301 | ||
1485 | 300 | public void testEnqueueArtistInPlaylist() { | 302 | public void testEnqueueArtistInPlaylist() { |
1487 | 301 | Uri playlistUri = Playlists.buildPlaylistSongsUri("playlist2-playlist_id"); | 303 | Uri playlistUri = Playlists.buildPlaylistUri("playlist2-playlist_id"); |
1488 | 302 | int songCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); | 304 | int songCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); |
1489 | 303 | assertEquals("Wrong song count of playlist.", 1, songCount); | 305 | assertEquals("Wrong song count of playlist.", 1, songCount); |
1490 | 304 | 306 | ||
1491 | @@ -311,10 +313,11 @@ | |||
1492 | 311 | int newSongCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); | 313 | int newSongCount = MusicProviderUtils.getPlaylistSongCount(mContext, playlistUri); |
1493 | 312 | assertEquals("Wrong new song count of playlist.", songCount + artistSongCount, newSongCount); | 314 | assertEquals("Wrong new song count of playlist.", songCount + artistSongCount, newSongCount); |
1494 | 313 | 315 | ||
1495 | 316 | Uri playlistSongsUri = Playlists.buildPlaylistSongsUri("playlist2-playlist_id"); | ||
1496 | 314 | Cursor cursor = null; | 317 | Cursor cursor = null; |
1497 | 315 | try { | 318 | try { |
1498 | 316 | String[] projection = new String[] { Songs.SONG_ID }; | 319 | String[] projection = new String[] { Songs.SONG_ID }; |
1500 | 317 | cursor = mResolver.query(playlistUri, projection, | 320 | cursor = mResolver.query(playlistSongsUri, projection, |
1501 | 318 | null, null, PlaylistSongs.DEFAULT_SORT); | 321 | null, null, PlaylistSongs.DEFAULT_SORT); |
1502 | 319 | if (cursor != null && cursor.isBeforeFirst()) { | 322 | if (cursor != null && cursor.isBeforeFirst()) { |
1503 | 320 | cursor.moveToFirst(); | 323 | cursor.moveToFirst(); |
1504 | 321 | 324 | ||
1505 | === modified file 'test/src/com/ubuntuone/android/music/ui/SongsPageTest.java' | |||
1506 | --- test/src/com/ubuntuone/android/music/ui/SongsPageTest.java 2012-11-08 14:14:54 +0000 | |||
1507 | +++ test/src/com/ubuntuone/android/music/ui/SongsPageTest.java 2012-11-28 17:49:20 +0000 | |||
1508 | @@ -100,6 +100,8 @@ | |||
1509 | 100 | assertNotNull("PlayerActivity was not started", | 100 | assertNotNull("PlayerActivity was not started", |
1510 | 101 | mInstrumentation.checkMonitorHit(mPlayerActivityMonitor, 1)); | 101 | mInstrumentation.checkMonitorHit(mPlayerActivityMonitor, 1)); |
1511 | 102 | activity.finish(); | 102 | activity.finish(); |
1512 | 103 | |||
1513 | 104 | mInstrumentation.waitForIdleSync(); | ||
1514 | 103 | } | 105 | } |
1515 | 104 | 106 | ||
1516 | 105 | public void testClearQueueAndPlaySongOnOnListItemClick() { | 107 | public void testClearQueueAndPlaySongOnOnListItemClick() { |
1517 | @@ -154,6 +156,8 @@ | |||
1518 | 154 | assertNotNull("PlayerActivity was not started", | 156 | assertNotNull("PlayerActivity was not started", |
1519 | 155 | mInstrumentation.checkMonitorHit(mPlayerActivityMonitor, 1)); | 157 | mInstrumentation.checkMonitorHit(mPlayerActivityMonitor, 1)); |
1520 | 156 | activity.finish(); | 158 | activity.finish(); |
1521 | 159 | |||
1522 | 160 | mInstrumentation.waitForIdleSync(); | ||
1523 | 157 | } | 161 | } |
1524 | 158 | 162 | ||
1525 | 159 | public void testOnStarContextItemSelected() { | 163 | public void testOnStarContextItemSelected() { |
Looks good!