Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96ad32db authored by Marie Janssen's avatar Marie Janssen
Browse files

AVRCP: Provide more media attributes

Add track number, total tracks, genre, and consolidate MediaAttribute
handling into a single place.

Bug: 28589463

Change-Id: I53049bc2a43c0f30af9639fbc3d6a02cd8a74900
parent f915433a
Loading
Loading
Loading
Loading
+114 −53
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ import android.content.res.Resources;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaMetadataRetriever;
import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
@@ -75,7 +75,7 @@ public final class Avrcp {
    private MediaSessionChangeListener mSessionChangeListener;
    private MediaController mMediaController;
    private MediaControllerListener mMediaControllerCb;
    private Metadata mMetadata;
    private MediaAttributes mMediaAttributes;
    private int mTransportControlFlags;
    private PlaybackState mCurrentPlayState;
    private int mPlayStatusChangedNT;
@@ -155,7 +155,7 @@ public final class Avrcp {
    }

    private Avrcp(Context context) {
        mMetadata = new Metadata();
        mMediaAttributes = new MediaAttributes(null);
        mCurrentPlayState = new PlaybackState.Builder().setState(PlaybackState.STATE_NONE, -1L, 0.0f).build();
        mPlayStatusChangedNT = NOTIFICATION_TYPE_CHANGED;
        mTrackChangedNT = NOTIFICATION_TYPE_CHANGED;
@@ -318,7 +318,9 @@ public final class Avrcp {
                textArray = new String[numAttr];
                for (int i = 0; i < numAttr; ++i) {
                    attrIds[i] = attrList.get(i).intValue();
                    textArray[i] = getAttributeString(attrIds[i]);
                    textArray[i] = mMediaAttributes.getString(attrIds[i]);
                    Log.v(TAG, "getAttributeString:attrId=" + attrIds[i] +
                               " str=" + textArray[i]);
                }
                getElementAttrRspNative(numAttr, attrIds, textArray);
                break;
@@ -691,36 +693,124 @@ public final class Avrcp {
        mTransportControlFlags = transportControlFlags;
    }

    class Metadata {
        private String artist;
        private String trackTitle;
        private String albumTitle;
    class MediaAttributes {
        private boolean exists;
        private String title;
        private String artistName;
        private String albumName;
        private String mediaNumber;
        private String mediaTotalNumber;
        private String genre;
        private String playingTimeMs;

        private static final int ATTR_TITLE = 1;
        private static final int ATTR_ARTIST_NAME = 2;
        private static final int ATTR_ALBUM_NAME = 3;
        private static final int ATTR_MEDIA_NUMBER = 4;
        private static final int ATTR_MEDIA_TOTAL_NUMBER = 5;
        private static final int ATTR_GENRE = 6;
        private static final int ATTR_PLAYING_TIME_MS = 7;


        public MediaAttributes(MediaMetadata data) {
            exists = data != null;
            if (!exists)
                return;

            artistName = stringOrBlank(data.getString(MediaMetadata.METADATA_KEY_ARTIST));
            albumName = stringOrBlank(data.getString(MediaMetadata.METADATA_KEY_ALBUM));
            mediaNumber = longStringOrBlank(data.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER));
            mediaTotalNumber = longStringOrBlank(data.getLong(MediaMetadata.METADATA_KEY_NUM_TRACKS));
            genre = stringOrBlank(data.getString(MediaMetadata.METADATA_KEY_GENRE));
            playingTimeMs = longStringOrBlank(data.getLong(MediaMetadata.METADATA_KEY_DURATION));

            // Try harder for the title.
            title = data.getString(MediaMetadata.METADATA_KEY_TITLE);

            if (title == null) {
                MediaDescription desc = data.getDescription();
                if (desc != null) {
                    CharSequence val = desc.getDescription();
                    if (val != null)
                        title = val.toString();
                }
            }

            if (title == null)
                title = new String();
        }

        public boolean equals(MediaAttributes other) {
            if (other == null)
                return false;

            if (exists != other.exists)
                return false;

            if (exists == false)
                return true;

            return (title.equals(other.title)) &&
                (artistName.equals(other.artistName)) &&
                (albumName.equals(other.albumName)) &&
                (mediaNumber.equals(other.mediaNumber)) &&
                (mediaTotalNumber.equals(other.mediaTotalNumber)) &&
                (genre.equals(other.genre)) &&
                (playingTimeMs.equals(other.playingTimeMs));
        }

        public String getString(int attrId) {
            if (!exists)
                return new String();

            switch (attrId) {
                case ATTR_TITLE:
                    return title;
                case ATTR_ARTIST_NAME:
                    return artistName;
                case ATTR_ALBUM_NAME:
                    return albumName;
                case ATTR_MEDIA_NUMBER:
                    return mediaNumber;
                case ATTR_MEDIA_TOTAL_NUMBER:
                    return mediaTotalNumber;
                case ATTR_GENRE:
                    return genre;
                case ATTR_PLAYING_TIME_MS:
                    return playingTimeMs;
                default:
                    return new String();
            }
        }

        public Metadata() {
            artist = null;
            trackTitle = null;
            albumTitle = null;
        private String stringOrBlank(String s) {
            return s == null ? new String() : s;
        }

        private String longStringOrBlank(Long s) {
            return s == null ? new String() : s.toString();
        }

        public String toString() {
            return "Metadata[artist=" + artist + " trackTitle=" + trackTitle + " albumTitle=" +
                    albumTitle + "]";
            if (!exists)
                return "[MediaAttributes: none]";

            return "[MediaAttributes: " + title + " - " + albumName + " by "
                + artistName + " (" + mediaNumber + "/" + mediaTotalNumber + ") "
                + genre + "]";
        }
    }

    private void updateMetadata(MediaMetadata data) {
        String oldMetadata = mMetadata.toString();
        MediaAttributes oldAttributes = mMediaAttributes;
        mMediaAttributes = new MediaAttributes(data);
        if (data == null) {
            mMetadata = new Metadata();
            mSongLengthMs = 0L;
        } else {
            mMetadata.artist = data.getString(MediaMetadata.METADATA_KEY_ARTIST);
            mMetadata.trackTitle = data.getString(MediaMetadata.METADATA_KEY_TITLE);
            mMetadata.albumTitle = data.getString(MediaMetadata.METADATA_KEY_ALBUM);
            mSongLengthMs = data.getLong(MediaMetadata.METADATA_KEY_DURATION);
        }
        if (!oldMetadata.equals(mMetadata.toString())) {
            Log.v(TAG, "Metadata Changed to " + mMetadata.toString());
        if (!oldAttributes.equals(mMediaAttributes)) {
            Log.v(TAG, "MediaAttributes Changed to " + mMediaAttributes.toString());
            mTrackNumber++;
            if (mTrackChangedNT == NOTIFICATION_TYPE_INTERIM) {
                mTrackChangedNT = NOTIFICATION_TYPE_CHANGED;
@@ -739,7 +829,7 @@ public final class Avrcp {
                mHandler.removeMessages(MESSAGE_PLAY_INTERVAL_TIMEOUT);
            }
        } else {
            Log.v(TAG, "Metadata updated but no change!");
            Log.v(TAG, "Updated " + mMediaAttributes.toString() + " but no change!");
        }

    }
@@ -867,35 +957,6 @@ public final class Avrcp {
        return songPosition;
    }

    private String getAttributeString(int attrId) {
        String attrStr = null;
        switch (attrId) {
            case MEDIA_ATTR_TITLE:
                attrStr = mMetadata.trackTitle;
                break;

            case MEDIA_ATTR_ARTIST:
                attrStr = mMetadata.artist;
                break;

            case MEDIA_ATTR_ALBUM:
                attrStr = mMetadata.albumTitle;
                break;

            case MEDIA_ATTR_PLAYING_TIME:
                if (mSongLengthMs != 0L) {
                    attrStr = Long.toString(mSongLengthMs);
                }
                break;

        }
        if (attrStr == null) {
            attrStr = new String();
        }
        Log.v(TAG, "getAttributeString:attrId=" + attrId + " str=" + attrStr);
        return attrStr;
    }

    private int convertPlayStateToPlayStatus(PlaybackState state) {
        int playStatus = PLAYSTATUS_ERROR;
        switch (state.getState()) {
@@ -1032,7 +1093,7 @@ public final class Avrcp {

    public void dump(StringBuilder sb) {
        sb.append("AVRCP:\n");
        ProfileService.println(sb, "mMetadata: " + mMetadata);
        ProfileService.println(sb, "mMediaAttributes: " + mMediaAttributes);
        ProfileService.println(sb, "mTransportControlFlags: " + mTransportControlFlags);
        ProfileService.println(sb, "mCurrentPlayState: " + mCurrentPlayState);
        ProfileService.println(sb, "mPlayStatusChangedNT: " + mPlayStatusChangedNT);