OSDN Git Service

Add ability to seek through track with circular motion
[android-x86/packages-apps-Eleven.git] / src / com / cyanogenmod / eleven / utils / MusicUtils.java
index 5ab0067..38e9ac0 100644 (file)
@@ -24,6 +24,7 @@ import android.content.Intent;
 import android.content.ServiceConnection;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -50,6 +51,7 @@ import com.cyanogenmod.eleven.loaders.PlaylistLoader;
 import com.cyanogenmod.eleven.loaders.PlaylistSongLoader;
 import com.cyanogenmod.eleven.loaders.SongLoader;
 import com.cyanogenmod.eleven.loaders.TopTracksLoader;
+import com.cyanogenmod.eleven.locale.LocaleUtils;
 import com.cyanogenmod.eleven.menu.FragmentMenuItems;
 import com.cyanogenmod.eleven.model.Album;
 import com.cyanogenmod.eleven.model.AlbumArtistDetails;
@@ -61,6 +63,8 @@ import com.cyanogenmod.eleven.service.MusicPlaybackTrack;
 
 import java.io.File;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.WeakHashMap;
 
 /**
@@ -72,8 +76,6 @@ public final class MusicUtils {
 
     public static IElevenService mService = null;
 
-    private static int sForegroundActivities = 0;
-
     private static final WeakHashMap<Context, ServiceBinder> mConnectionMap;
 
     private static final long[] sEmptyList;
@@ -85,6 +87,9 @@ public final class MusicUtils {
     public static final String MUSIC_ONLY_SELECTION = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1"
                     + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''"; //$NON-NLS-2$
 
+    public static final long UPDATE_FREQUENCY_MS = 500;
+    public static final long UPDATE_FREQUENCY_FAST_MS = 30;
+
     static {
         mConnectionMap = new WeakHashMap<Context, ServiceBinder>();
         sEmptyList = new long[0];
@@ -107,7 +112,8 @@ public final class MusicUtils {
         }
         final ContextWrapper contextWrapper = new ContextWrapper(realActivity);
         contextWrapper.startService(new Intent(contextWrapper, MusicPlaybackService.class));
-        final ServiceBinder binder = new ServiceBinder(callback);
+        final ServiceBinder binder = new ServiceBinder(callback,
+                contextWrapper.getApplicationContext());
         if (contextWrapper.bindService(
                 new Intent().setClass(contextWrapper, MusicPlaybackService.class), binder, 0)) {
             mConnectionMap.put(contextWrapper, binder);
@@ -136,14 +142,16 @@ public final class MusicUtils {
 
     public static final class ServiceBinder implements ServiceConnection {
         private final ServiceConnection mCallback;
+        private final Context mContext;
 
         /**
          * Constructor of <code>ServiceBinder</code>
          *
          * @param context The {@link ServiceConnection} to use
          */
-        public ServiceBinder(final ServiceConnection callback) {
+        public ServiceBinder(final ServiceConnection callback, final Context context) {
             mCallback = callback;
+            mContext = context;
         }
 
         @Override
@@ -152,6 +160,7 @@ public final class MusicUtils {
             if (mCallback != null) {
                 mCallback.onServiceConnected(className, service);
             }
+            MusicUtils.initPlaybackServiceWithSettings(mContext);
         }
 
         @Override
@@ -269,6 +278,40 @@ public final class MusicUtils {
     }
 
     /**
+     * Initialize playback service with values from Settings
+     */
+    public static void initPlaybackServiceWithSettings(final Context context) {
+        MusicUtils.setShakeToPlayEnabled(
+                PreferenceUtils.getInstance(context).getShakeToPlay());
+        MusicUtils.setShowAlbumArtOnLockscreen(
+                PreferenceUtils.getInstance(context).getShowAlbumArtOnLockscreen());
+    }
+
+    /**
+     * Set shake to play status
+     */
+    public static void setShakeToPlayEnabled(final boolean enabled) {
+        try {
+            if (mService != null) {
+                mService.setShakeToPlayEnabled(enabled);
+            }
+        } catch (final RemoteException ignored) {
+        }
+    }
+
+    /**
+     * Set show album art on lockscreen
+     */
+    public static void setShowAlbumArtOnLockscreen(final boolean enabled) {
+        try {
+            if (mService != null) {
+                mService.setLockscreenAlbumArt(enabled);
+            }
+        } catch (final RemoteException ignored) {
+        }
+    }
+
+    /**
      * Changes to the next track asynchronously
      */
     public static void asyncNext(final Context context) {
@@ -831,15 +874,6 @@ public final class MusicUtils {
             if (forceShuffle) {
                 mService.setShuffleMode(MusicPlaybackService.SHUFFLE_NORMAL);
             }
-            final long currentId = mService.getAudioId();
-            final int currentQueuePosition = getQueuePosition();
-            if (position != -1 && currentQueuePosition == position && currentId == list[position]) {
-                final long[] playlist = getQueue();
-                if (Arrays.equals(list, playlist)) {
-                    mService.play();
-                    return;
-                }
-            }
             if (position < 0) {
                 position = 0;
             }
@@ -1546,28 +1580,6 @@ public final class MusicUtils {
     }
 
     /**
-     * Used to build and show a notification when Apollo is sent into the
-     * background
-     *
-     * @param context The {@link Context} to use.
-     */
-    public static void notifyForegroundStateChanged(final Context context, boolean inForeground) {
-        int old = sForegroundActivities;
-        if (inForeground) {
-            sForegroundActivities++;
-        } else {
-            sForegroundActivities--;
-        }
-
-        if (old == 0 || sForegroundActivities == 0) {
-            final Intent intent = new Intent(context, MusicPlaybackService.class);
-            intent.setAction(MusicPlaybackService.FOREGROUND_STATE_CHANGED);
-            intent.putExtra(MusicPlaybackService.NOW_IN_FOREGROUND, sForegroundActivities != 0);
-            context.startService(intent);
-        }
-    }
-
-    /**
      * Perminately deletes item(s) from the user's device
      *
      * @param context The {@link Context} to use.
@@ -1684,34 +1696,17 @@ public final class MusicUtils {
      * This will take a name, removes things like "the", "an", etc
      * as well as special characters, then find the localized label
      * @param name Name to get the label of
-     * @param trimName boolean flag to run the trimmer on the name
      * @return the localized label of the bucket that the name falls into
      */
-    public static String getLocalizedBucketLetter(String name, boolean trimName) {
+    public static String getLocalizedBucketLetter(String name) {
         if (name == null || name.length() == 0) {
             return null;
         }
 
-        if (trimName) {
-            name = getTrimmedName(name);
-        }
+        name = getTrimmedName(name);
 
         if (name.length() > 0) {
-            String lbl = LocaleUtils.getInstance().getLabel(name);
-            // For now let's cap it to latin alphabet and the # sign
-            // since chinese characters are resulting in " " and other random
-            // characters but the sort doesn't match the sql sort so it is
-            // not quite sorted
-            if (lbl != null && lbl.length() > 0) {
-                char ch = lbl.charAt(0);
-                if ((ch < 'A' || ch > 'Z') && ch != '#') {
-                    return null;
-                }
-            }
-
-            if (lbl != null && lbl.length() > 0) {
-                return lbl;
-            }
+            return LocaleUtils.getInstance().getLabel(name);
         }
 
         return null;
@@ -1748,47 +1743,6 @@ public final class MusicUtils {
     }
 
     /**
-     * Determines the correct item attribute to use for a given sort request and generates the
-     * localized bucket for that attribute
-     * @param item
-     * @param sortOrder
-     * @param <T>
-     * @return
-     */
-    public static <T> String getLocalizedBucketLetterByAttribute(T item, String sortOrder) {
-        if (item instanceof Song) {
-            // we aren't 'trimming' certain attributes - a flag for such attributes
-            boolean trimName = true;
-            String attributeToLocalize = ((Song)item).mSongName;
-
-            // select Song attribute based on the sort order
-            if (sortOrder.equals(SortOrder.SongSortOrder.SONG_ARTIST) ) {
-                attributeToLocalize = ((Song)item).mArtistName;
-                trimName = false;
-            } else if (sortOrder.equals(SortOrder.SongSortOrder.SONG_ALBUM) ) {
-                attributeToLocalize = ((Song)item).mAlbumName;
-            }
-
-            return getLocalizedBucketLetter(attributeToLocalize, trimName);
-        } else if (item instanceof Artist) {
-            return getLocalizedBucketLetter(((Artist)item).mArtistName, true);
-        } else if (item instanceof Album) {
-            // we aren't 'trimming' certain attributes - a flag for such attributes
-            boolean trimName = true;
-            String attributeToLocalize = ((Album)item).mAlbumName;
-
-            if (sortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_ARTIST) ) {
-                attributeToLocalize = ((Album)item).mArtistName;
-                trimName = false;
-            }
-
-            return getLocalizedBucketLetter(attributeToLocalize, trimName);
-        }
-
-        return null;
-    }
-
-    /**
      *
      * @param sortOrder values are mostly derived from SortOrder.class or could also be any sql
      *                  order clause
@@ -1797,4 +1751,23 @@ public final class MusicUtils {
     public static boolean isSortOrderDesending(String sortOrder) {
         return sortOrder.endsWith(" DESC");
     }
+
+    /**
+     * Takes a collection of items and builds a comma-separated list of them
+     * @param items collection of items
+     * @return comma-separted list of items
+     */
+    public static final <E> String buildCollectionAsString(Collection<E> items) {
+        Iterator<E> iterator = items.iterator();
+        StringBuilder str = new StringBuilder();
+        if (iterator.hasNext()) {
+            str.append(iterator.next());
+            while (iterator.hasNext()) {
+                str.append(",");
+                str.append(iterator.next());
+            }
+        }
+
+        return str.toString();
+    }
 }