OSDN Git Service

eleven: Add support for the MediaSession queue
authorSteve Kondik <steve@cyngn.com>
Thu, 6 Oct 2016 21:07:44 +0000 (14:07 -0700)
committerSteve Kondik <steve@cyngn.com>
Thu, 6 Oct 2016 22:23:51 +0000 (15:23 -0700)
 * This allows remote controls to view the contents of the queue
   and select the active track based on the queue id.

Change-Id: I205225864d10044ef60c3fe2bc877525c437d506

src/com/cyanogenmod/eleven/MusicPlaybackService.java

index 13aa01c..afade74 100644 (file)
@@ -28,8 +28,8 @@ import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
 import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.database.MatrixCursor;
@@ -37,6 +37,7 @@ import android.graphics.Bitmap;
 import android.hardware.SensorManager;
 import android.media.AudioManager;
 import android.media.AudioManager.OnAudioFocusChangeListener;
+import android.media.MediaDescription;
 import android.media.MediaMetadata;
 import android.media.MediaPlayer;
 import android.media.audiofx.AudioEffect;
@@ -51,6 +52,7 @@ import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.provider.BaseColumns;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Audio.AlbumColumns;
 import android.provider.MediaStore.Audio.AudioColumns;
@@ -81,6 +83,7 @@ import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.ListIterator;
 import java.util.Random;
+import java.util.TreeMap;
 import java.util.TreeSet;
 
 /**
@@ -733,6 +736,10 @@ public class MusicPlaybackService extends Service {
                 releaseServiceUiAndStop();
             }
             @Override
+            public void onSkipToQueueItem(long index) {
+                setQueuePosition((int) index);
+            }
+            @Override
             public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
                 if (Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) {
                     KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
@@ -1566,6 +1573,7 @@ public class MusicPlaybackService extends Service {
         if (what.equals(PLAYSTATE_CHANGED) || what.equals(POSITION_CHANGED)) {
             mSession.setPlaybackState(new PlaybackState.Builder()
                     .setActions(playBackStateActions)
+                    .setActiveQueueItemId(getQueuePosition())
                     .setState(playState, position(), 1.0f).build());
         } else if (what.equals(META_CHANGED) || what.equals(QUEUE_CHANGED)) {
             Bitmap albumArt = getAlbumArt(false).getBitmap();
@@ -1592,12 +1600,68 @@ public class MusicPlaybackService extends Service {
                             mShowAlbumArtOnLockscreen ? albumArt : null)
                     .build());
 
+            if (what.equals(QUEUE_CHANGED)) {
+                updateMediaSessionQueue();
+            }
+
             mSession.setPlaybackState(new PlaybackState.Builder()
                     .setActions(playBackStateActions)
+                    .setActiveQueueItemId(getQueuePosition())
                     .setState(playState, position(), 1.0f).build());
         }
     }
 
+    private synchronized void updateMediaSessionQueue() {
+        if (getQueuePosition() < 0 || getQueueSize() == 0) {
+            mSession.setQueue(null);
+            return;
+        }
+
+        final StringBuilder selection = new StringBuilder();
+        for (long id : getQueue()) {
+            if (selection.length() > 0) {
+                selection.append(",");
+            }
+            selection.append(id);
+        }
+        selection.insert(0, MediaStore.Audio.Media._ID + " IN (");
+        selection.append(")");
+
+        Cursor c = getApplicationContext().getContentResolver().query(
+                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
+                new String[]{BaseColumns._ID, AudioColumns.TITLE, AudioColumns.ARTIST},
+                selection.toString(), null, null);
+
+        final TreeMap<Integer, MediaSession.QueueItem> items = new TreeMap<>();
+        if (c != null) {
+            try {
+                while (c.moveToNext()) {
+                    long id = c.getLong(c.getColumnIndexOrThrow(BaseColumns._ID));
+                    MediaDescription desc = new MediaDescription.Builder()
+                            .setTitle(c.getString(
+                                    c.getColumnIndexOrThrow(AudioColumns.TITLE)))
+                            .setSubtitle(c.getString(
+                                    c.getColumnIndexOrThrow(AudioColumns.ARTIST)))
+                            .build();
+
+                    int index = -1;
+                    for (int i = 0; i < getQueueSize(); i++) {
+                        if (getQueue()[i] == id) {
+                            index = i;
+                            break;
+                        }
+                    }
+                    if (index >= 0) {
+                        items.put(index, new MediaSession.QueueItem(desc, index));
+                    }
+                }
+            } finally {
+                c.close();
+            }
+        }
+        mSession.setQueue(new ArrayList<MediaSession.QueueItem>(items.values()));
+    }
+
     private Notification buildNotification() {
         final String albumName = getAlbumName();
         final String artistName = getArtistName();