OSDN Git Service

theme engine fixes
[android-x86/packages-apps-Eleven.git] / src / com / android / music / PlaylistBrowserActivity.java
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.music;
18
19 import java.text.Collator;
20 import java.util.ArrayList;
21
22 import android.app.ListActivity;
23 import android.content.AsyncQueryHandler;
24 import android.content.BroadcastReceiver;
25 import android.content.ComponentName;
26 import android.content.ContentResolver;
27 import android.content.ContentUris;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.IntentFilter;
31 import android.content.ServiceConnection;
32 import android.content.SharedPreferences;
33 import android.content.pm.PackageManager;
34 import android.content.pm.PackageManager.NameNotFoundException;
35 import android.content.res.Configuration;
36 import android.content.res.Resources;
37 import android.database.Cursor;
38 import android.database.MatrixCursor;
39 import android.database.MergeCursor;
40 import android.database.sqlite.SQLiteException;
41 import android.media.AudioManager;
42 import android.net.Uri;
43 import android.os.Bundle;
44 import android.os.Handler;
45 import android.os.IBinder;
46 import android.os.Message;
47 import android.os.RemoteException;
48 import android.provider.BaseColumns;
49 import android.provider.MediaStore;
50 import android.provider.MediaStore.Audio.AudioColumns;
51 import android.util.Log;
52 import android.view.ContextMenu;
53 import android.view.ContextMenu.ContextMenuInfo;
54 import android.view.GestureDetector;
55 import android.view.GestureDetector.SimpleOnGestureListener;
56 import android.view.KeyEvent;
57 import android.view.Menu;
58 import android.view.MenuItem;
59 import android.view.MotionEvent;
60 import android.view.View;
61 import android.view.ViewGroup;
62 import android.view.Window;
63 import android.widget.AdapterView.AdapterContextMenuInfo;
64 import android.widget.FrameLayout;
65 import android.widget.ImageButton;
66 import android.widget.ImageView;
67 import android.widget.LinearLayout;
68 import android.widget.ListView;
69 import android.widget.ProgressBar;
70 import android.widget.RelativeLayout;
71 import android.widget.SimpleCursorAdapter;
72 import android.widget.TabWidget;
73 import android.widget.TextView;
74 import android.widget.Toast;
75
76 import com.android.music.MusicUtils.ServiceToken;
77
78 public class PlaylistBrowserActivity extends ListActivity implements
79                 View.OnCreateContextMenuListener, MusicUtils.Defs {
80         private static final String TAG = "PlaylistBrowserActivity";
81         private static final int DELETE_PLAYLIST = CHILD_MENU_BASE + 1;
82         private static final int EDIT_PLAYLIST = CHILD_MENU_BASE + 2;
83         private static final int RENAME_PLAYLIST = CHILD_MENU_BASE + 3;
84         private static final int CHANGE_WEEKS = CHILD_MENU_BASE + 4;
85         private static final long RECENTLY_ADDED_PLAYLIST = -1;
86         private static final long ALL_SONGS_PLAYLIST = -2;
87         private static final long PODCASTS_PLAYLIST = -3;
88         private PlaylistListAdapter mAdapter;
89         boolean mAdapterSent;
90         private static int mLastListPosCourse = -1;
91         private static int mLastListPosFine = -1;
92
93         private boolean mCreateShortcut;
94         private ServiceToken mToken;
95         private ServiceToken mOSC;
96         private IMediaPlaybackService mService = null;
97         private SharedPreferences mPreferences;
98         // Artist tab layout
99         public LinearLayout mPlaylistTab;
100         public TabWidget mButtonBar;
101         public TextView mButtonBarArtist;
102         public TextView mButtonBarAlbum;
103         public TextView mButtonBarSong;
104         public TextView mButtonBarPlaylist;
105         public TextView mButtonBarNP;
106         public RelativeLayout mGroup;
107         public RelativeLayout mChild;
108         // Smaller now playing window buttons
109         private LinearLayout mNowPlaying;
110         private ImageView mInfoDivider;
111         private ProgressBar mProgress;
112         private ImageButton mDoSearch;
113         private ImageButton mMarket;
114         private ImageButton mNext;
115         private ImageButton mPlay;
116         private ImageButton mPlusPlaylist;
117         private ImageButton mPrev;
118         private ImageButton mShare;
119         private ImageButton mFlow;
120         // Back button long press
121         public String back_button_db;
122         // Smaller now playing window swipe gesture
123         public GestureDetector gestureDetector;
124         private static final int SWIPE_MIN_DISTANCE = 120;
125         private static final int SWIPE_MAX_OFF_PATH = 250;
126         private static final int SWIPE_THRESHOLD_VELOCITY = 200;
127         private String np_swipe_gesture_db;
128         // Swipe tabs
129         private GestureDetector swipetabs;
130         // ADW Theme constants
131         public static final int THEME_ITEM_BACKGROUND = 0;
132         public static final int THEME_ITEM_FOREGROUND = 1;
133         public static final int THEME_ITEM_TEXT_DRAWABLE = 2;
134
135         public PlaylistBrowserActivity() {
136         }
137
138         /** Called when the activity is first created. */
139         @Override
140         public void onCreate(Bundle icicle) {
141                 super.onCreate(icicle);
142                 mPreferences = getSharedPreferences(
143                                 MusicSettingsActivity.PREFERENCES_FILE, MODE_PRIVATE);
144
145                 final Intent intent = getIntent();
146                 final String action = intent.getAction();
147                 if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
148                         mCreateShortcut = true;
149                 }
150
151                 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
152                 requestWindowFeature(Window.FEATURE_NO_TITLE);
153                 setVolumeControlStream(AudioManager.STREAM_MUSIC);
154                 mOSC = MusicUtils.bindToService(this, osc);
155                 mToken = MusicUtils.bindToService(this, new ServiceConnection() {
156                         public void onServiceConnected(ComponentName classname, IBinder obj) {
157                                 if (Intent.ACTION_VIEW.equals(action)) {
158                                         Bundle b = intent.getExtras();
159                                         if (b == null) {
160                                                 Log.w(TAG, "Unexpected:getExtras() returns null.");
161                                         } else {
162                                                 try {
163                                                         long id = Long.parseLong(b.getString("playlist"));
164                                                         if (id == RECENTLY_ADDED_PLAYLIST) {
165                                                                 playRecentlyAdded();
166                                                         } else if (id == PODCASTS_PLAYLIST) {
167                                                                 playPodcasts();
168                                                         } else if (id == ALL_SONGS_PLAYLIST) {
169                                                                 long[] list = MusicUtils
170                                                                                 .getAllSongs(PlaylistBrowserActivity.this);
171                                                                 if (list != null) {
172                                                                         MusicUtils.playAll(
173                                                                                         PlaylistBrowserActivity.this, list,
174                                                                                         0);
175                                                                 }
176                                                         } else {
177                                                                 MusicUtils.playPlaylist(
178                                                                                 PlaylistBrowserActivity.this, id);
179                                                         }
180                                                 } catch (NumberFormatException e) {
181                                                         Log.w(TAG, "Playlist id missing or broken");
182                                                 }
183                                         }
184                                         finish();
185                                         return;
186                                 }
187                                 MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this);
188                         }
189
190                         public void onServiceDisconnected(ComponentName classname) {
191                         }
192
193                 });
194                 IntentFilter f = new IntentFilter();
195                 f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
196                 f.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
197                 f.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
198                 f.addDataScheme("file");
199                 registerReceiver(mScanListener, f);
200
201                 setContentView(R.layout.media_picker_activity);
202                 MusicUtils.updateButtonBar(this, R.id.playlisttab);
203                 ListView lv = getListView();
204                 lv.setOnCreateContextMenuListener(this);
205                 lv.setTextFilterEnabled(true);
206
207                 mAdapter = (PlaylistListAdapter) getLastNonConfigurationInstance();
208                 if (mAdapter == null) {
209                         // Log.i("@@@", "starting query");
210                         mAdapter = new PlaylistListAdapter(getApplication(), this,
211                                         R.layout.track_list_item, mPlaylistCursor,
212                                         new String[] { MediaStore.Audio.Playlists.NAME },
213                                         new int[] { android.R.id.text1 });
214                         setListAdapter(mAdapter);
215                         setTitle(R.string.working_playlists);
216                         getPlaylistCursor(mAdapter.getQueryHandler(), null);
217                 } else {
218                         mAdapter.setActivity(this);
219                         setListAdapter(mAdapter);
220                         mPlaylistCursor = mAdapter.getCursor();
221                         // If mPlaylistCursor is null, this can be because it doesn't have
222                         // a cursor yet (because the initial query that sets its cursor
223                         // is still in progress), or because the query failed.
224                         // In order to not flash the error dialog at the user for the
225                         // first case, simply retry the query when the cursor is null.
226                         // Worst case, we end up doing the same query twice.
227                         if (mPlaylistCursor != null) {
228                                 init(mPlaylistCursor);
229                         } else {
230                                 setTitle(R.string.working_playlists);
231                                 getPlaylistCursor(mAdapter.getQueryHandler(), null);
232                         }
233                 }
234                 // Swipe up gesture
235                 gestureDetector = new GestureDetector(new NowPlayingGesture());
236                 View nowplayingview = (View) findViewById(R.id.nowplaying);
237                 // Tab swipe
238                 swipetabs = new GestureDetector(new TabSwipe());
239                 View mainview = (View) findViewById(android.R.id.list);
240
241                 // Set the touch listener for the main view to be our custom gesture
242                 // listener
243                 mainview.setOnTouchListener(new View.OnTouchListener() {
244                         public boolean onTouch(View v, MotionEvent event) {
245                                 if (swipetabs.onTouchEvent(event)) {
246                                         return false;
247                                 }
248                                 return false;
249                         }
250                 });
251
252                 // Smaller now playing window buttons
253                 mShare = (ImageButton) findViewById(R.id.share_song);
254                 mPlay = (ImageButton) findViewById(R.id.media_play);
255                 mNext = (ImageButton) findViewById(R.id.media_next);
256                 mPrev = (ImageButton) findViewById(R.id.media_prev);
257                 mMarket = (ImageButton) findViewById(R.id.market_music);
258                 mDoSearch = (ImageButton) findViewById(R.id.doSearch);
259                 mPlusPlaylist = (ImageButton) findViewById(R.id.plus_playlist);
260                 mFlow = (ImageButton) findViewById(R.id.overFlow);
261                 // I found that without setting the onClickListeners in Portrait mode
262                 // only, flipping into Landscape force closes.
263                 if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
264                         // Smaller now playing window actions
265                         mPlusPlaylist.setOnClickListener(mAddPlaylist);
266                         mDoSearch.setOnClickListener(mDoSearchListener);
267                         mMarket.setOnClickListener(mMarketSearch);
268                         mPlay.setOnClickListener(mMediaPlay);
269                         mNext.setOnClickListener(mMediaNext);
270                         mPrev.setOnClickListener(mMediaPrev);
271                         mShare.setOnClickListener(mShareSong);
272                         mFlow.setOnClickListener(mOverFlow);
273                         // I only want this to show in the Playlist activity
274                         if (mPreferences.getBoolean(
275                                         MusicSettingsActivity.KEY_ENABLE_NEW_PLAYLIST_BUTTON, true)) {
276                                 mPlusPlaylist.setVisibility(View.VISIBLE);
277                         } else {
278                                 mPlusPlaylist.setVisibility(View.GONE);
279                         } // Swipe gesture
280                         nowplayingview.setOnTouchListener(new View.OnTouchListener() {
281                                 public boolean onTouch(View vee, MotionEvent nowplayingevent) {
282                                         if (gestureDetector.onTouchEvent(nowplayingevent)) {
283                                                 return false;
284                                         }
285                                         return false;
286                                 }
287                         });
288                 }
289                 // ADW: Load the specified theme
290                 String themePackage = MusicUtils.getThemePackageName(this,
291                                 MusicSettingsActivity.THEME_DEFAULT);
292                 PackageManager pm = getPackageManager();
293                 Resources themeResources = null;
294                 if (!themePackage.equals(MusicSettingsActivity.THEME_DEFAULT)) {
295                         try {
296                                 themeResources = pm.getResourcesForApplication(themePackage);
297                         } catch (NameNotFoundException e) {
298                                 // ADW The saved theme was uninstalled so we save the
299                                 // default one
300                                 MusicUtils.setThemePackageName(this,
301                                                 MusicSettingsActivity.THEME_DEFAULT);
302                         }
303                 }
304                 // Set Views for themes
305                 if (themeResources != null) {
306                         // Artist tab
307                         mPlaylistTab = (LinearLayout) findViewById(R.id.album_tab);
308                         mButtonBar = (TabWidget) findViewById(R.id.buttonbar);
309                         mButtonBarArtist = (TextView) findViewById(R.id.artisttab);
310                         mButtonBarAlbum = (TextView) findViewById(R.id.albumtab);
311                         mButtonBarSong = (TextView) findViewById(R.id.songtab);
312                         mButtonBarPlaylist = (TextView) findViewById(R.id.playlisttab);
313                         mButtonBarNP = (TextView) findViewById(R.id.nowplayingtab);
314                         ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
315                                         themePackage, "tab_playlist", mPlaylistTab,
316                                         THEME_ITEM_BACKGROUND);
317                         ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
318                                         themePackage, "buttonbar", mButtonBar,
319                                         THEME_ITEM_BACKGROUND);
320                         ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
321                                         themePackage, "tab_bg_artist", mButtonBarArtist,
322                                         THEME_ITEM_BACKGROUND);
323                         ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
324                                         themePackage, "tab_bg_album", mButtonBarAlbum,
325                                         THEME_ITEM_BACKGROUND);
326                         ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
327                                         themePackage, "tab_bg_song", mButtonBarSong,
328                                         THEME_ITEM_BACKGROUND);
329                         ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
330                                         themePackage, "tab_bg_playlist", mButtonBarPlaylist,
331                                         THEME_ITEM_BACKGROUND);
332                         ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
333                                         themePackage, "tab_bg_nowplaying", mButtonBarNP,
334                                         THEME_ITEM_BACKGROUND);
335                         // Small now playing window
336                         mNowPlaying = (LinearLayout) findViewById(R.id.nowplaying);
337                         mInfoDivider = (ImageView) findViewById(R.id.info_divider);
338                         mProgress = (ProgressBar) findViewById(R.id.progress);
339                         mShare = (ImageButton) findViewById(R.id.share_song);
340                         mPlay = (ImageButton) findViewById(R.id.media_play);
341                         mNext = (ImageButton) findViewById(R.id.media_next);
342                         mPrev = (ImageButton) findViewById(R.id.media_prev);
343                         mMarket = (ImageButton) findViewById(R.id.market_music);
344                         mDoSearch = (ImageButton) findViewById(R.id.doSearch);
345                         mFlow = (ImageButton) findViewById(R.id.overFlow);
346                         mPlusPlaylist = (ImageButton) findViewById(R.id.plus_playlist);
347                         if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
348                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
349                                                 themePackage, "snp_background", mNowPlaying,
350                                                 THEME_ITEM_BACKGROUND);
351                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
352                                                 themePackage, "snp_progress", mProgress,
353                                                 THEME_ITEM_BACKGROUND);
354                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
355                                                 themePackage, "snp_info_divider", mInfoDivider,
356                                                 THEME_ITEM_BACKGROUND);
357                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
358                                                 themePackage, "snp_share", mShare,
359                                                 THEME_ITEM_FOREGROUND);
360                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
361                                                 themePackage, "snp_play", mPlay, THEME_ITEM_FOREGROUND);
362                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
363                                                 themePackage, "snp_next", mNext, THEME_ITEM_FOREGROUND);
364                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
365                                                 themePackage, "snp_prev", mPrev, THEME_ITEM_FOREGROUND);
366                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
367                                                 themePackage, "snp_market", mMarket,
368                                                 THEME_ITEM_FOREGROUND);
369                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
370                                                 themePackage, "snp_search", mDoSearch,
371                                                 THEME_ITEM_FOREGROUND);
372                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
373                                                 themePackage, "snp_flow", mFlow, THEME_ITEM_FOREGROUND);
374                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
375                                                 themePackage, "snp_plus_playlist", mPlusPlaylist,
376                                                 THEME_ITEM_FOREGROUND);
377                         }
378                 }
379         }
380
381         // Tab Swipe
382         class TabSwipe extends SimpleOnGestureListener {
383                 @Override
384                 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
385                                 float velocityY) {
386                         Intent intent = new Intent(Intent.ACTION_PICK);
387
388                         try {
389                                 if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
390                                         return false;
391                                 if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
392                                                 && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
393                                         intent.setDataAndType(Uri.EMPTY,
394                                                         "vnd.android.cursor.dir/artistalbum");
395                                         intent.putExtra("withtabs", true);
396                                         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
397                                         startActivity(intent);
398                                         finish();
399                                         PlaylistBrowserActivity.this.overridePendingTransition(
400                                                         R.anim.slide_in_right, R.anim.slide_out_left);
401                                         return true;
402                                 } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
403                                                 && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
404                                         intent.setDataAndType(Uri.EMPTY,
405                                                         "vnd.android.cursor.dir/track");
406                                         intent.putExtra("withtabs", true);
407                                         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
408                                         startActivity(intent);
409                                         finish();
410                                         PlaylistBrowserActivity.this.overridePendingTransition(
411                                                         R.anim.slide_in_left, R.anim.slide_out_right);
412                                         return true;
413
414                                 }
415
416                         } catch (Exception e) {
417                                 Log.e("Fling", "There was an error processing the Fling event:"
418                                                 + e.getMessage());
419                         }
420                         return true;
421                 }
422
423                 // It is necessary to return true from onDown for the onFling event to
424                 // register
425                 @Override
426                 public boolean onDown(MotionEvent e) {
427                         return true;
428                 }
429         }
430
431         // Swipe gesture
432         class NowPlayingGesture extends SimpleOnGestureListener {
433                 @Override
434                 public boolean onFling(MotionEvent e3, MotionEvent e4, float vX,
435                                 float vY) {
436                         np_swipe_gesture_db = mPreferences.getString("np_swipe_gesture",
437                                         "0");
438                         if (np_swipe_gesture_db.equals("0")) {
439                                 if (e3.getY() - e4.getY() > SWIPE_MIN_DISTANCE
440                                                 && Math.abs(vY) > SWIPE_THRESHOLD_VELOCITY) {
441                                         // NONE
442                                 }
443                         }
444
445                         np_swipe_gesture_db = mPreferences.getString("np_swipe_gesture",
446                                         "1");
447                         if (np_swipe_gesture_db.equals("1")) {
448                                 if (e3.getY() - e4.getY() > SWIPE_MIN_DISTANCE
449                                                 && Math.abs(vY) > SWIPE_THRESHOLD_VELOCITY) {
450                                         doPauseResume();
451                                 }
452                         }
453
454                         np_swipe_gesture_db = mPreferences.getString("np_swipe_gesture",
455                                         "2");
456                         if (np_swipe_gesture_db.equals("2")) {
457                                 if (e3.getY() - e4.getY() > SWIPE_MIN_DISTANCE
458                                                 && Math.abs(vY) > SWIPE_THRESHOLD_VELOCITY) {
459                                         doNext();
460                                 }
461                         }
462                         np_swipe_gesture_db = mPreferences.getString("np_swipe_gesture",
463                                         "3");
464                         if (np_swipe_gesture_db.equals("3")) {
465                                 if (e3.getY() - e4.getY() > SWIPE_MIN_DISTANCE
466                                                 && Math.abs(vY) > SWIPE_THRESHOLD_VELOCITY) {
467                                         doPrev();
468                                 }
469                         }
470                         return false;
471
472                 }
473
474                 @Override
475                 public boolean onDown(MotionEvent f) {
476                         return true;
477                 }
478         }
479
480         // Smaller now playing window OnClickListerners
481         private View.OnClickListener mMarketSearch = new View.OnClickListener() {
482                 public void onClick(View v) {
483                         Uri marketUri = null;
484                         try {
485                                 marketUri = Uri.parse("market://search?q= "
486                                                 + mService.getArtistName());
487                         } catch (RemoteException e) {
488                                 // TODO Auto-generated catch block
489                                 e.printStackTrace();
490                         }
491                         Intent marketIntent = new Intent(Intent.ACTION_VIEW)
492                                         .setData(marketUri);
493                         startActivity(marketIntent);
494                         finish();
495
496                 }
497         };
498         private View.OnClickListener mShareSong = new View.OnClickListener() {
499
500                 @Override
501                 public void onClick(View v) {
502                         // TODO Auto-generated method stub
503                         try {
504                                 shareCurrentTrack();
505                         } catch (RemoteException e) {
506                                 // TODO Auto-generated catch block
507                                 e.printStackTrace();
508                         }
509
510                 }
511
512         };
513
514         private String shareCurrentTrack() throws RemoteException {
515                 if (mService.getTrackName() == null || mService.getArtistName() == null) {
516
517                 }
518
519                 Intent shareIntent = new Intent();
520                 String currentTrackMessage = "Now listening to: "
521                                 + mService.getTrackName() + " by " + mService.getArtistName();
522
523                 shareIntent.setAction(Intent.ACTION_SEND);
524                 shareIntent.setType("text/plain");
525                 shareIntent.putExtra(Intent.EXTRA_TEXT, currentTrackMessage);
526
527                 startActivity(Intent.createChooser(shareIntent, "Share track using"));
528                 return currentTrackMessage;
529         }
530
531         private View.OnClickListener mAddPlaylist = new View.OnClickListener() {
532                 public void onClick(View v) {
533                         Intent intent;
534                         intent = new Intent();
535                         intent.setClass(PlaylistBrowserActivity.this, CreatePlaylist.class);
536                         startActivityForResult(intent, NEW_PLAYLIST);
537                         ;
538                 }
539         };
540         private View.OnClickListener mOverFlow = new View.OnClickListener() {
541                 public void onClick(View v) {
542                         openOptionsMenu();
543                 }
544         };
545         private View.OnClickListener mDoSearchListener = new View.OnClickListener() {
546                 public void onClick(View v) {
547                         onSearchRequested();
548                 }
549         };
550         private View.OnClickListener mMediaPlay = new View.OnClickListener() {
551                 public void onClick(View v) {
552                         doPauseResume();
553                 }
554         };
555         private View.OnClickListener mMediaNext = new View.OnClickListener() {
556                 public void onClick(View v) {
557                         doNext();
558                 }
559         };
560         private View.OnClickListener mMediaPrev = new View.OnClickListener() {
561                 public void onClick(View v) {
562                         doPrev();
563                 }
564         };
565
566         @Override
567         public Object onRetainNonConfigurationInstance() {
568                 PlaylistListAdapter a = mAdapter;
569                 mAdapterSent = true;
570                 return a;
571         }
572
573         @Override
574         public void onDestroy() {
575                 ListView lv = getListView();
576                 if (lv != null) {
577                         mLastListPosCourse = lv.getFirstVisiblePosition();
578                         View cv = lv.getChildAt(0);
579                         if (cv != null) {
580                                 mLastListPosFine = cv.getTop();
581                         }
582                 }
583                 MusicUtils.unbindFromService(mToken);
584                 MusicUtils.unbindFromService(mOSC);
585                 // If we have an adapter and didn't send it off to another activity yet,
586                 // we should
587                 // close its cursor, which we do by assigning a null cursor to it. Doing
588                 // this
589                 // instead of closing the cursor directly keeps the framework from
590                 // accessing
591                 // the closed cursor later.
592                 if (!mAdapterSent && mAdapter != null) {
593                         mAdapter.changeCursor(null);
594                 }
595                 // Because we pass the adapter to the next activity, we need to make
596                 // sure it doesn't keep a reference to this activity. We can do this
597                 // by clearing its DatasetObservers, which setListAdapter(null) does.
598                 setListAdapter(null);
599                 mAdapter = null;
600                 unregisterReceiver(mScanListener);
601                 super.onDestroy();
602         }
603
604         private void startPlayback() {
605
606                 if (mService == null)
607                         return;
608                 Intent intent = getIntent();
609                 String filename = "";
610                 Uri uri = intent.getData();
611                 if (uri != null && uri.toString().length() > 0) {
612                         // If this is a file:// URI, just use the path directly instead
613                         // of going through the open-from-filedescriptor codepath.
614                         String scheme = uri.getScheme();
615                         if ("file".equals(scheme)) {
616                                 filename = uri.getPath();
617                         } else {
618                                 filename = uri.toString();
619                         }
620                         try {
621                                 refreshProgress();
622                                 mService.stop();
623                                 mService.openFile(filename);
624                                 mService.play();
625                                 setIntent(new Intent());
626                         } catch (Exception ex) {
627                                 Log.d("MediaPlaybackActivity", "couldn't start playback: " + ex);
628                         }
629                 }
630         }
631
632         private ServiceConnection osc = new ServiceConnection() {
633                 public void onServiceConnected(ComponentName classname, IBinder obj) {
634                         mService = IMediaPlaybackService.Stub.asInterface(obj);
635                         startPlayback();
636                         // This is for orientation changes or entering the tab from a
637                         // different activity
638                         if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
639                                 setPauseButtonImage();
640                                 // This is so the controls will load correctly according to the
641                                 // user's settings
642                                 MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this);
643                         }
644                         try {
645                                 if (mService.getAudioId() >= 0 || mService.isPlaying()
646                                                 || mService.getPath() != null) {
647                                         return;
648                                 }
649                         } catch (RemoteException ex) {
650                         }
651                         if (getIntent().getData() == null) {
652                                 Intent intent = new Intent(Intent.ACTION_MAIN);
653                                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
654                                 intent.setClass(PlaylistBrowserActivity.this,
655                                                 MusicBrowserActivity.class);
656                                 startActivity(intent);
657                         }
658                 }
659
660                 public void onServiceDisconnected(ComponentName classname) {
661                         mService = null;
662                 }
663         };
664
665         @Override
666         public void onResume() {
667                 super.onResume();
668
669                 IntentFilter f = new IntentFilter();
670                 f.addAction(MediaPlaybackService.META_CHANGED);
671                 f.addAction(MediaPlaybackService.QUEUE_CHANGED);
672                 f.addAction(MediaPlaybackService.PROGRESSBAR_CHANGED);
673                 f.addAction(MediaPlaybackService.PLAYSTATE_CHANGED);
674                 registerReceiver(mTrackListListener, f);
675
676                 MusicUtils.setSpinnerState(this);
677         }
678
679         @Override
680         public void onPause() {
681                 super.onPause();
682                 unregisterReceiver(mTrackListListener);
683                 mReScanHandler.removeCallbacksAndMessages(null);
684                 super.onPause();
685         }
686
687         private BroadcastReceiver mTrackListListener = new BroadcastReceiver() {
688                 @Override
689                 public void onReceive(Context context, Intent intent) {
690                         String action = intent.getAction();
691                         getListView().invalidateViews();
692                         MusicUtils.updateNowPlaying(PlaylistBrowserActivity.this);
693                         if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
694                                 refreshProgress();
695                                 if (action.equals(MediaPlaybackService.PLAYSTATE_CHANGED)) {
696                                         setPauseButtonImage();
697                                 }
698                         }
699                 }
700         };
701         private BroadcastReceiver mScanListener = new BroadcastReceiver() {
702                 @Override
703                 public void onReceive(Context context, Intent intent) {
704                         MusicUtils.setSpinnerState(PlaylistBrowserActivity.this);
705                         mReScanHandler.sendEmptyMessage(0);
706                 }
707         };
708
709         private Handler mReScanHandler = new Handler() {
710                 @Override
711                 public void handleMessage(Message msg) {
712                         if (mAdapter != null) {
713                                 getPlaylistCursor(mAdapter.getQueryHandler(), null);
714                         }
715                 }
716         };
717
718         public void init(Cursor cursor) {
719
720                 if (mAdapter == null) {
721                         return;
722                 }
723                 mAdapter.changeCursor(cursor);
724
725                 if (mPlaylistCursor == null) {
726                         MusicUtils.displayDatabaseError(this);
727                         closeContextMenu();
728                         mReScanHandler.sendEmptyMessageDelayed(0, 1000);
729                         return;
730                 }
731
732                 // restore previous position
733                 if (mLastListPosCourse >= 0) {
734                         getListView().setSelectionFromTop(mLastListPosCourse,
735                                         mLastListPosFine);
736                         mLastListPosCourse = -1;
737                 }
738                 MusicUtils.hideDatabaseError(this);
739                 MusicUtils.updateButtonBar(this, R.id.playlisttab);
740                 setTitle();
741         }
742
743         private void setTitle() {
744                 setTitle(R.string.playlists_title);
745         }
746
747         @Override
748         public boolean onCreateOptionsMenu(Menu menu) {
749                 if (!mCreateShortcut) {
750                         menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle);
751                         menu.add(0, SETTINGS, 0, R.string.settings);
752
753                 }
754                 return super.onCreateOptionsMenu(menu);
755         }
756
757         @Override
758         public boolean onPrepareOptionsMenu(Menu menu) {
759                 MusicUtils.setPartyShuffleMenuIcon(menu);
760                 return super.onPrepareOptionsMenu(menu);
761         }
762
763         @Override
764         public boolean onOptionsItemSelected(MenuItem item) {
765                 Intent intent;
766                 switch (item.getItemId()) {
767                 case PARTY_SHUFFLE:
768                         MusicUtils.togglePartyShuffle();
769                         return true;
770                 case SETTINGS:
771                         intent = new Intent();
772                         intent.setClass(this, MusicSettingsActivity.class);
773                         startActivityForResult(intent, SETTINGS);
774                         return true;
775                 }
776                 return super.onOptionsItemSelected(item);
777         }
778
779         public void onCreateContextMenu(ContextMenu menu, View view,
780                         ContextMenuInfo menuInfoIn) {
781                 if (mCreateShortcut) {
782                         return;
783                 }
784
785                 AdapterContextMenuInfo mi = (AdapterContextMenuInfo) menuInfoIn;
786
787                 menu.add(0, PLAY_SELECTION, 0, R.string.play_selection);
788
789                 if (mi.id >= 0 /* || mi.id == PODCASTS_PLAYLIST */) {
790                         menu.add(0, DELETE_PLAYLIST, 0, R.string.delete_playlist_menu);
791                 }
792
793                 if (mi.id == RECENTLY_ADDED_PLAYLIST) {
794                         menu.add(0, EDIT_PLAYLIST, 0, R.string.edit_playlist_menu);
795                 }
796
797                 if (mi.id >= 0) {
798                         menu.add(0, RENAME_PLAYLIST, 0, R.string.rename_playlist_menu);
799                 }
800
801                 mPlaylistCursor.moveToPosition(mi.position);
802                 menu.setHeaderTitle(mPlaylistCursor.getString(mPlaylistCursor
803                                 .getColumnIndexOrThrow(MediaStore.Audio.Playlists.NAME)));
804         }
805
806         @Override
807         public boolean onContextItemSelected(MenuItem item) {
808                 AdapterContextMenuInfo mi = (AdapterContextMenuInfo) item.getMenuInfo();
809                 switch (item.getItemId()) {
810                 case PLAY_SELECTION:
811                         if (mi.id == RECENTLY_ADDED_PLAYLIST) {
812                                 playRecentlyAdded();
813                         } else if (mi.id == PODCASTS_PLAYLIST) {
814                                 playPodcasts();
815                         } else {
816                                 MusicUtils.playPlaylist(this, mi.id);
817                         }
818                         break;
819                 case DELETE_PLAYLIST:
820                         Uri uri = ContentUris.withAppendedId(
821                                         MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, mi.id);
822                         getContentResolver().delete(uri, null, null);
823                         Toast.makeText(this, R.string.playlist_deleted_message,
824                                         Toast.LENGTH_SHORT).show();
825                         if (mPlaylistCursor.getCount() == 0) {
826                                 setTitle(R.string.no_playlists_title);
827                         }
828                         break;
829                 case EDIT_PLAYLIST:
830                         if (mi.id == RECENTLY_ADDED_PLAYLIST) {
831                                 Intent intent = new Intent();
832                                 intent.setClass(this, WeekSelector.class);
833                                 startActivityForResult(intent, CHANGE_WEEKS);
834                                 return true;
835                         } else {
836                                 Log.e(TAG, "should not be here");
837                         }
838                         break;
839                 case RENAME_PLAYLIST:
840                         Intent intent = new Intent();
841                         intent.setClass(this, RenamePlaylist.class);
842                         intent.putExtra("rename", mi.id);
843                         startActivityForResult(intent, RENAME_PLAYLIST);
844                         break;
845                 }
846                 return true;
847         }
848
849         @Override
850         protected void onActivityResult(int requestCode, int resultCode,
851                         Intent intent) {
852                 switch (requestCode) {
853                 case SCAN_DONE:
854                         if (resultCode == RESULT_CANCELED) {
855                                 finish();
856                         } else if (mAdapter != null) {
857                                 getPlaylistCursor(mAdapter.getQueryHandler(), null);
858                         }
859                         break;
860                 }
861         }
862
863         @Override
864         protected void onListItemClick(ListView l, View v, int position, long id) {
865                 if (mCreateShortcut) {
866                         final Intent shortcut = new Intent();
867                         shortcut.setAction(Intent.ACTION_VIEW);
868                         shortcut.setDataAndType(Uri.EMPTY,
869                                         "vnd.android.cursor.dir/playlist");
870                         shortcut.putExtra("playlist", String.valueOf(id));
871
872                         final Intent intent = new Intent();
873                         intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcut);
874                         intent.putExtra(Intent.EXTRA_SHORTCUT_NAME,
875                                         ((TextView) v.findViewById(R.id.line1)).getText());
876                         intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
877                                         Intent.ShortcutIconResource.fromContext(this,
878                                                         R.drawable.ic_launcher_shortcut_music_playlist));
879
880                         setResult(RESULT_OK, intent);
881                         finish();
882                         return;
883                 }
884                 if (id == RECENTLY_ADDED_PLAYLIST) {
885                         Intent intent = new Intent(Intent.ACTION_PICK);
886                         intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
887                         intent.putExtra("playlist", "recentlyadded");
888                         startActivity(intent);
889                 } else if (id == PODCASTS_PLAYLIST) {
890                         Intent intent = new Intent(Intent.ACTION_PICK);
891                         intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
892                         intent.putExtra("playlist", "podcasts");
893                         startActivity(intent);
894                 } else {
895                         Intent intent = new Intent(Intent.ACTION_EDIT);
896                         intent.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/track");
897                         intent.putExtra("playlist", Long.valueOf(id).toString());
898                         startActivity(intent);
899                 }
900         }
901
902         private void playRecentlyAdded() {
903                 // do a query for all songs added in the last X weeks
904                 int X = MusicUtils.getIntPref(this, "numweeks", 2) * (3600 * 24 * 7);
905                 final String[] ccols = new String[] { MediaStore.Audio.Media._ID };
906                 String where = MediaStore.MediaColumns.DATE_ADDED + ">"
907                                 + (System.currentTimeMillis() / 1000 - X);
908                 Cursor cursor = MusicUtils.query(this,
909                                 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ccols, where,
910                                 null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
911
912                 if (cursor == null) {
913                         // Todo: show a message
914                         return;
915                 }
916                 try {
917                         int len = cursor.getCount();
918                         long[] list = new long[len];
919                         for (int i = 0; i < len; i++) {
920                                 cursor.moveToNext();
921                                 list[i] = cursor.getLong(0);
922                         }
923                         MusicUtils.playAll(this, list, 0);
924                 } catch (SQLiteException ex) {
925                 } finally {
926                         cursor.close();
927                 }
928         }
929
930         private void playPodcasts() {
931                 // do a query for all files that are podcasts
932                 final String[] ccols = new String[] { MediaStore.Audio.Media._ID };
933                 Cursor cursor = MusicUtils.query(this,
934                                 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ccols,
935                                 MediaStore.Audio.Media.IS_PODCAST + "=1", null,
936                                 MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
937
938                 if (cursor == null) {
939                         // Todo: show a message
940                         return;
941                 }
942                 try {
943                         int len = cursor.getCount();
944                         long[] list = new long[len];
945                         for (int i = 0; i < len; i++) {
946                                 cursor.moveToNext();
947                                 list[i] = cursor.getLong(0);
948                         }
949                         MusicUtils.playAll(this, list, 0);
950                 } catch (SQLiteException ex) {
951                 } finally {
952                         cursor.close();
953                 }
954         }
955
956         String[] mCols = new String[] { MediaStore.Audio.Playlists._ID,
957                         MediaStore.Audio.Playlists.NAME };
958
959         private Cursor getPlaylistCursor(AsyncQueryHandler async,
960                         String filterstring) {
961
962                 StringBuilder where = new StringBuilder();
963                 where.append(MediaStore.Audio.Playlists.NAME + " != ''");
964
965                 // Add in the filtering constraints
966                 String[] keywords = null;
967                 if (filterstring != null) {
968                         String[] searchWords = filterstring.split(" ");
969                         keywords = new String[searchWords.length];
970                         Collator col = Collator.getInstance();
971                         col.setStrength(Collator.PRIMARY);
972                         for (int i = 0; i < searchWords.length; i++) {
973                                 keywords[i] = '%' + searchWords[i] + '%';
974                         }
975                         for (int i = 0; i < searchWords.length; i++) {
976                                 where.append(" AND ");
977                                 where.append(MediaStore.Audio.Playlists.NAME + " LIKE ?");
978                         }
979                 }
980
981                 String whereclause = where.toString();
982
983                 if (async != null) {
984                         async.startQuery(0, null,
985                                         MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, mCols,
986                                         whereclause, keywords, MediaStore.Audio.Playlists.NAME);
987                         return null;
988                 }
989                 Cursor c = null;
990                 c = MusicUtils.query(this,
991                                 MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, mCols,
992                                 whereclause, keywords, MediaStore.Audio.Playlists.NAME);
993
994                 return mergedCursor(c);
995         }
996
997         private Cursor mergedCursor(Cursor c) {
998                 if (c == null) {
999                         return null;
1000                 }
1001                 if (c instanceof MergeCursor) {
1002                         // this shouldn't happen, but fail gracefully
1003                         Log.d("PlaylistBrowserActivity", "Already wrapped");
1004                         return c;
1005                 }
1006                 MatrixCursor autoplaylistscursor = new MatrixCursor(mCols);
1007                 if (mCreateShortcut) {
1008                         ArrayList<Object> all = new ArrayList<Object>(2);
1009                         all.add(ALL_SONGS_PLAYLIST);
1010                         all.add(getString(R.string.play_all));
1011                         autoplaylistscursor.addRow(all);
1012                 }
1013                 ArrayList<Object> recent = new ArrayList<Object>(2);
1014                 recent.add(RECENTLY_ADDED_PLAYLIST);
1015                 recent.add(getString(R.string.recentlyadded));
1016                 autoplaylistscursor.addRow(recent);
1017
1018                 // check if there are any podcasts
1019                 Cursor counter = MusicUtils.query(this,
1020                                 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
1021                                 new String[] { "count(*)" }, "is_podcast=1", null, null);
1022                 if (counter != null) {
1023                         counter.moveToFirst();
1024                         int numpodcasts = counter.getInt(0);
1025                         counter.close();
1026                         if (numpodcasts > 0) {
1027                                 ArrayList<Object> podcasts = new ArrayList<Object>(2);
1028                                 podcasts.add(PODCASTS_PLAYLIST);
1029                                 podcasts.add(getString(R.string.podcasts_listitem));
1030                                 autoplaylistscursor.addRow(podcasts);
1031                         }
1032                 }
1033
1034                 Cursor cc = new MergeCursor(new Cursor[] { autoplaylistscursor, c });
1035                 return cc;
1036         }
1037
1038         static class PlaylistListAdapter extends SimpleCursorAdapter {
1039                 int mTitleIdx;
1040                 int mIdIdx;
1041                 private PlaylistBrowserActivity mActivity = null;
1042                 private AsyncQueryHandler mQueryHandler;
1043                 private String mConstraint = null;
1044                 private boolean mConstraintIsValid = false;
1045
1046                 class QueryHandler extends AsyncQueryHandler {
1047                         QueryHandler(ContentResolver res) {
1048                                 super(res);
1049                         }
1050
1051                         @Override
1052                         protected void onQueryComplete(int token, Object cookie,
1053                                         Cursor cursor) {
1054                                 // Log.i("@@@", "query complete: " + cursor.getCount() + "   " +
1055                                 // mActivity);
1056                                 if (cursor != null) {
1057                                         cursor = mActivity.mergedCursor(cursor);
1058                                 }
1059                                 mActivity.init(cursor);
1060                         }
1061                 }
1062
1063                 PlaylistListAdapter(Context context,
1064                                 PlaylistBrowserActivity currentactivity, int layout,
1065                                 Cursor cursor, String[] from, int[] to) {
1066                         super(context, layout, cursor, from, to);
1067                         mActivity = currentactivity;
1068                         getColumnIndices(cursor);
1069                         mQueryHandler = new QueryHandler(context.getContentResolver());
1070                 }
1071
1072                 private void getColumnIndices(Cursor cursor) {
1073                         if (cursor != null) {
1074                                 mTitleIdx = cursor
1075                                                 .getColumnIndexOrThrow(MediaStore.Audio.Playlists.NAME);
1076                                 mIdIdx = cursor
1077                                                 .getColumnIndexOrThrow(MediaStore.Audio.Playlists._ID);
1078                         }
1079                 }
1080
1081                 public void setActivity(PlaylistBrowserActivity newactivity) {
1082                         mActivity = newactivity;
1083                 }
1084
1085                 public AsyncQueryHandler getQueryHandler() {
1086                         return mQueryHandler;
1087                 }
1088
1089                 private View.OnClickListener mCML = new View.OnClickListener() {
1090                         public void onClick(View v) {
1091                                 v.showContextMenu();
1092
1093                         }
1094                 };
1095
1096                 @Override
1097                 public void bindView(View view, Context context, Cursor cursor) {
1098
1099                         // ADW: Load the specified theme
1100                         String themePackage = MusicUtils.getThemePackageName(context,
1101                                         MusicSettingsActivity.THEME_DEFAULT);
1102                         PackageManager pm = context.getPackageManager();
1103                         Resources themeResources = null;
1104                         if (!themePackage.equals(MusicSettingsActivity.THEME_DEFAULT)) {
1105                                 try {
1106                                         themeResources = pm
1107                                                         .getResourcesForApplication(themePackage);
1108                                 } catch (NameNotFoundException e) {
1109                                         // ADW The saved theme was uninstalled so we save the
1110                                         // default one
1111                                         MusicUtils.setThemePackageName(context,
1112                                                         MusicSettingsActivity.THEME_DEFAULT);
1113                                 }
1114                         }
1115
1116                         TextView tv = (TextView) view.findViewById(R.id.line1);
1117
1118                         String name = cursor.getString(mTitleIdx);
1119                         tv.setText(name);
1120
1121                         long id = cursor.getLong(mIdIdx);
1122
1123                         ImageView iv = (ImageView) view.findViewById(R.id.icon);
1124
1125                         ViewGroup.LayoutParams p = iv.getLayoutParams();
1126                         p.width = ViewGroup.LayoutParams.WRAP_CONTENT;
1127                         p.height = ViewGroup.LayoutParams.WRAP_CONTENT;
1128
1129                         iv = (ImageView) view.findViewById(R.id.play_indicator);
1130                         iv.setVisibility(View.GONE);
1131
1132                         view.findViewById(R.id.line2).setVisibility(View.GONE);
1133
1134                         FrameLayout mContextMenu = (FrameLayout) view
1135                                         .findViewById(R.id.second_column_icon);
1136                         iv.setVisibility(View.GONE);
1137                         mContextMenu.setOnClickListener(mCML);
1138                         ImageView cM = (ImageView) view.findViewById(R.id.CM);
1139                         if (themeResources != null) {
1140
1141                                 int line1 = themeResources.getIdentifier(
1142                                                 "playlist_tab_playlist_name_color", "color",
1143                                                 themePackage);
1144                                 if (line1 != 0) {
1145                                         tv.setTextColor(themeResources.getColor(line1));
1146                                 }
1147                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
1148                                                 themePackage, "bt_context_menu", cM,
1149                                                 THEME_ITEM_FOREGROUND);
1150                         }
1151                 }
1152
1153                 @Override
1154                 public void changeCursor(Cursor cursor) {
1155                         if (mActivity.isFinishing() && cursor != null) {
1156                                 cursor.close();
1157                                 cursor = null;
1158                         }
1159                         if (cursor != mActivity.mPlaylistCursor) {
1160                                 mActivity.mPlaylistCursor = cursor;
1161                                 super.changeCursor(cursor);
1162                                 getColumnIndices(cursor);
1163                         }
1164                 }
1165
1166                 @Override
1167                 public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
1168                         String s = constraint.toString();
1169                         if (mConstraintIsValid
1170                                         && ((s == null && mConstraint == null) || (s != null && s
1171                                                         .equals(mConstraint)))) {
1172                                 return getCursor();
1173                         }
1174                         Cursor c = mActivity.getPlaylistCursor(null, s);
1175                         mConstraint = s;
1176                         mConstraintIsValid = true;
1177                         return c;
1178                 }
1179         }
1180
1181         private Cursor mPlaylistCursor;
1182
1183         // Methods for media control
1184         private void doPauseResume() {
1185                 try {
1186                         if (mService != null) {
1187                                 if (mService.isPlaying()) {
1188                                         mService.pause();
1189                                 } else {
1190                                         mService.play();
1191                                 }
1192                                 if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
1193                                         setPauseButtonImage();
1194                                 }
1195                         }
1196                 } catch (RemoteException ex) {
1197                 }
1198         }
1199
1200         private void setPauseButtonImage() {
1201                 // ADW: Load the specified theme
1202                 String themePackage = MusicUtils.getThemePackageName(this,
1203                                 MusicSettingsActivity.THEME_DEFAULT);
1204                 PackageManager pm = getPackageManager();
1205                 Resources themeResources = null;
1206                 if (!themePackage.equals(MusicSettingsActivity.THEME_DEFAULT)) {
1207                         try {
1208                                 themeResources = pm.getResourcesForApplication(themePackage);
1209                         } catch (NameNotFoundException e) {
1210                                 // ADW The saved theme was uninstalled so we save the
1211                                 // default one
1212                                 MusicUtils.setThemePackageName(this,
1213                                                 MusicSettingsActivity.THEME_DEFAULT);
1214                         }
1215                 }
1216                 try {
1217                         if (mService != null && mService.isPlaying()) {
1218                                 mPlay.setImageResource(R.drawable.ic_media_pause);
1219                                 ArtistAlbumBrowserActivity
1220                                                 .loadThemeResource(themeResources, themePackage,
1221                                                                 "snp_pause", mPlay, THEME_ITEM_FOREGROUND);
1222                         } else {
1223                                 mPlay.setImageResource(R.drawable.ic_appwidget_music_play);
1224                                 ArtistAlbumBrowserActivity.loadThemeResource(themeResources,
1225                                                 themePackage, "snp_play", mPlay, THEME_ITEM_FOREGROUND);
1226                         }
1227                 } catch (RemoteException ex) {
1228                 }
1229         }
1230
1231         private void refreshProgress() {
1232                 ProgressBar mProgress = (ProgressBar) findViewById(R.id.progress);
1233                 mProgress.setMax(1000);
1234                 try {
1235                         if ((MusicUtils.sService.position() >= 0)
1236                                         && (MusicUtils.sService.duration() > 0)) {
1237                                 mProgress.setProgress((int) (1000 * MusicUtils.sService
1238                                                 .position() / MusicUtils.sService.duration()));
1239                         } else {
1240                                 mProgress.setProgress(1000);
1241                         }
1242                 } catch (Exception e) {
1243                         // TODO Auto-generated catch block
1244                         e.printStackTrace();
1245                 }
1246
1247         }
1248
1249         private void doPrev() {
1250                 if (mService == null)
1251                         return;
1252                 try {
1253                         if (mService.position() < 2000) {
1254                                 mService.prev();
1255                         } else {
1256                                 mService.seek(0);
1257                                 mService.play();
1258                         }
1259                         setPauseButtonImage();
1260                 } catch (RemoteException ex) {
1261                 }
1262         }
1263
1264         private void doNext() {
1265                 if (mService == null)
1266                         return;
1267                 try {
1268                         mService.next();
1269                         setPauseButtonImage();
1270                 } catch (RemoteException ex) {
1271                 }
1272         }
1273
1274         @Override
1275         public boolean onKeyLongPress(int keyCode, KeyEvent event) {
1276                 if (keyCode == KeyEvent.KEYCODE_BACK) {
1277                         back_button_db = mPreferences.getString("back_button_db", "0");
1278                         if (back_button_db.equals("0")) {
1279                                 MusicUtils.togglePartyShuffle();
1280                                 return true;
1281                         }
1282                         if (keyCode == KeyEvent.KEYCODE_BACK) {
1283                                 back_button_db = mPreferences.getString("back_button_db", "1");
1284                                 if (back_button_db.equals("1")) {
1285                                         playRecentlyAdded();
1286                                         return true;
1287                                 }
1288
1289                         }
1290                         if (keyCode == KeyEvent.KEYCODE_BACK) {
1291                                 back_button_db = mPreferences.getString("back_button_db", "2");
1292                                 if (back_button_db.equals("2")) {
1293                                         Cursor cursor;
1294                                         cursor = MusicUtils.query(this,
1295                                                         MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
1296                                                         new String[] { BaseColumns._ID },
1297                                                         AudioColumns.IS_MUSIC + "=1", null,
1298                                                         MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
1299                                         if (cursor != null) {
1300                                                 MusicUtils.shuffleAll(this, cursor);
1301                                                 cursor.close();
1302                                                 return true;
1303                                         }
1304                                 }
1305                         }
1306                 }
1307                 return super.onKeyLongPress(keyCode, event);
1308         }
1309 }