1 /*
2  * Copyright 2019 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.car.media.testmediaapp.loader;
18 
19 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ADVERTISEMENT;
20 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ALBUM;
21 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ALBUM_ART;
22 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST;
23 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI;
24 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ART;
25 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ARTIST;
26 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ART_URI;
27 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_AUTHOR;
28 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_BT_FOLDER_TYPE;
29 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_COMPILATION;
30 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_COMPOSER;
31 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DATE;
32 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISC_NUMBER;
33 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_DESCRIPTION;
34 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON;
35 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI;
36 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE;
37 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE;
38 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DOWNLOAD_STATUS;
39 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_DURATION;
40 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_GENRE;
41 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_MEDIA_ID;
42 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_MEDIA_URI;
43 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_NUM_TRACKS;
44 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_RATING;
45 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_TITLE;
46 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER;
47 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_USER_RATING;
48 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_WRITER;
49 import static android.support.v4.media.MediaMetadataCompat.METADATA_KEY_YEAR;
50 
51 import static com.android.car.media.testmediaapp.loader.TmaLoaderUtils.enumNamesToValues;
52 
53 import android.support.v4.media.MediaMetadataCompat;
54 import android.util.Log;
55 
56 import com.android.car.media.testmediaapp.TmaPublicProvider;
57 
58 import org.json.JSONException;
59 import org.json.JSONObject;
60 
61 import java.util.EnumSet;
62 import java.util.Iterator;
63 import java.util.Map;
64 import java.util.Set;
65 
66 
67 class TmaMediaMetadataReader {
68 
69     private final static String TAG = "TmaMetadataReader";
70 
71     private enum ValueType {
72         LONG,
73         TEXT,
74         BITMAP,
75         RATING
76     }
77 
78     /** The name of each entry is the key used in the json file. */
79     private enum MetadataKey {
80         TITLE               (METADATA_KEY_TITLE,                ValueType.TEXT),
81         ARTIST              (METADATA_KEY_ARTIST,               ValueType.TEXT),
82         DURATION            (METADATA_KEY_DURATION,             ValueType.LONG),
83         ALBUM               (METADATA_KEY_ALBUM,                ValueType.TEXT),
84         AUTHOR              (METADATA_KEY_AUTHOR,               ValueType.TEXT),
85         WRITER              (METADATA_KEY_WRITER,               ValueType.TEXT),
86         COMPOSER            (METADATA_KEY_COMPOSER,             ValueType.TEXT),
87         COMPILATION         (METADATA_KEY_COMPILATION,          ValueType.TEXT),
88         DATE                (METADATA_KEY_DATE,                 ValueType.TEXT),
89         YEAR                (METADATA_KEY_YEAR,                 ValueType.LONG),
90         GENRE               (METADATA_KEY_GENRE,                ValueType.TEXT),
91         TRACK_NUMBER        (METADATA_KEY_TRACK_NUMBER,         ValueType.LONG),
92         NUM_TRACKS          (METADATA_KEY_NUM_TRACKS,           ValueType.LONG),
93         DISC_NUMBER         (METADATA_KEY_DISC_NUMBER,          ValueType.LONG),
94         ALBUM_ARTIST        (METADATA_KEY_ALBUM_ARTIST,         ValueType.TEXT),
95         ART                 (METADATA_KEY_ART,                  ValueType.BITMAP),
96         ART_URI             (METADATA_KEY_ART_URI,              ValueType.TEXT),
97         ALBUM_ART           (METADATA_KEY_ALBUM_ART,            ValueType.BITMAP),
98         ALBUM_ART_URI       (METADATA_KEY_ALBUM_ART_URI,        ValueType.TEXT),
99         USER_RATING         (METADATA_KEY_USER_RATING,          ValueType.RATING),
100         RATING              (METADATA_KEY_RATING,               ValueType.RATING),
101         DISPLAY_TITLE       (METADATA_KEY_DISPLAY_TITLE,        ValueType.TEXT),
102         DISPLAY_SUBTITLE    (METADATA_KEY_DISPLAY_SUBTITLE,     ValueType.TEXT),
103         DISPLAY_DESCRIPTION (METADATA_KEY_DISPLAY_DESCRIPTION,  ValueType.TEXT),
104         DISPLAY_ICON        (METADATA_KEY_DISPLAY_ICON,         ValueType.BITMAP),
105         DISPLAY_ICON_URI    (METADATA_KEY_DISPLAY_ICON_URI,     ValueType.TEXT),
106         MEDIA_ID            (METADATA_KEY_MEDIA_ID,             ValueType.TEXT),
107         BT_FOLDER_TYPE      (METADATA_KEY_BT_FOLDER_TYPE,       ValueType.LONG),
108         MEDIA_URI           (METADATA_KEY_MEDIA_URI,            ValueType.TEXT),
109         ADVERTISEMENT       (METADATA_KEY_ADVERTISEMENT,        ValueType.LONG),
110         DOWNLOAD_STATUS     (METADATA_KEY_DOWNLOAD_STATUS,      ValueType.LONG);
111 
112         /** The full name of the key in {@link MediaMetadataCompat}. */
113         final String mLongName;
114         /** The type of the key's value in {@link MediaMetadataCompat}. */
115         final ValueType mKeyType;
116 
MetadataKey(String longName, ValueType valueType)117         MetadataKey(String longName, ValueType valueType) {
118             mLongName = longName;
119             mKeyType = valueType;
120         }
121     }
122 
123     private static TmaMediaMetadataReader sInstance;
124 
getInstance()125     synchronized static TmaMediaMetadataReader getInstance() {
126         if (sInstance == null) {
127             sInstance = new TmaMediaMetadataReader();
128         }
129         return sInstance;
130     }
131 
132     private final Map<String, MetadataKey> mMetadataKeys;
133     private final Set<MetadataKey> mUriKeys;
134 
TmaMediaMetadataReader()135     private TmaMediaMetadataReader() {
136         mMetadataKeys = enumNamesToValues(MetadataKey.values());
137         mUriKeys = EnumSet.of(MetadataKey.ART_URI, MetadataKey.ALBUM_ART_URI,
138                 MetadataKey.DISPLAY_ICON_URI, MetadataKey.MEDIA_URI);
139     }
140 
141 
fromJson(JSONObject object)142     MediaMetadataCompat fromJson(JSONObject object) throws JSONException {
143         MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
144         Iterator<String> keys = object.keys();
145         while (keys.hasNext()) {
146             String jsonKey = keys.next();
147             MetadataKey key = mMetadataKeys.get(jsonKey);
148             if (key != null) {
149                 switch (key.mKeyType) {
150                     case LONG:
151                         builder.putLong(key.mLongName, object.getLong(jsonKey));
152                         break;
153                     case TEXT:
154                         String value = object.getString(jsonKey);
155                         if (mUriKeys.contains(key)) {
156                             value = TmaPublicProvider.buildUriString(value);
157                         }
158                         builder.putString(key.mLongName, value);
159                         break;
160                     case BITMAP:
161                     case RATING:
162                         Log.e(TAG, "Ignoring unsupported type: " + key.mKeyType + " for key: "
163                         + jsonKey + " / " + key.mLongName);
164                 }
165             } else {
166                 Log.e(TAG, "Ignoring unsupported key: " + jsonKey);
167             }
168         }
169         return builder.build();
170     }
171 }
172