1 /*
2 * Copyright (C) 2010 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 #include <MimeTypeUtil.h>
18 #include <utils/Log.h>
19
20 namespace android {
21
22 #undef LOG_TAG
23 #define LOG_TAG "MimeTypeUtil"
24
25 #ifdef DRM_OMA_FL_ENGINE_DEBUG
26 #define LOG_NDEBUG 0
27 #define LOG_DEBUG(...) ALOGD(__VA_ARGS__)
28 #else
29 #define LOG_DEBUG(...)
30 #endif
31
32 enum {
33 MIMETYPE_AUDIO = 0,
34 MIMETYPE_APPLICATION = 1,
35 MIMETYPE_IMAGE = 2,
36 MIMETYPE_VIDEO = 3,
37 MIMETYPE_LAST = -1,
38 };
39
40 struct MimeGroup{
41 int type; // Audio, video,.. use the enum values
42 const char* pGroup; // "audio/", "video/",.. should contain the last "/"
43 int size; // Number of bytes. e.g. "audio/" = 6 bytes
44 };
45
46 struct MimeTypeList{
47 int type;
48 const char* pMimeExt; // Everything after the '/' e.g. audio/x-mpeg -> "x-mpeg"
49 int size; // Number of bytes. e.g. "x-mpeg" = 6 bytes
50 const char* pMimeType; // Mimetype that should be returned
51 };
52
53
54 // Known mimetypes by android
55 static const char mime_type_audio_mpeg[] = "audio/mpeg";
56 static const char mime_type_audio_3gpp[] = "audio/3gpp";
57 static const char mime_type_audio_amr[] = "audio/amr-wb";
58 static const char mime_type_audio_aac[] = "audio/mp4a-latm";
59 static const char mime_type_audio_wav[] = "audio/wav";
60
61 static const char mime_type_video_mpeg4[] = "video/mpeg4";
62 static const char mime_type_video_3gpp[] = "video/3gpp";
63
64 // Known mimetype groups
65 static const char mime_group_audio[] = "audio/";
66 static const char mime_group_application[] = "application/";
67 static const char mime_group_image[] = "image/";
68 static const char mime_group_video[] = "video/";
69 static const char mime_type_unsupported[] = "unsupported/drm.mimetype";
70
71 static struct MimeGroup mimeGroup[] = {
72 {MIMETYPE_AUDIO, mime_group_audio, sizeof(mime_group_audio)-1},
73 {MIMETYPE_APPLICATION, mime_group_application, sizeof(mime_group_application)-1},
74 {MIMETYPE_IMAGE, mime_group_image, sizeof(mime_group_image)-1},
75 {MIMETYPE_VIDEO, mime_group_video, sizeof(mime_group_video)-1},
76 {MIMETYPE_LAST, NULL, 0} // Must be last entry
77 };
78
79 // List of all mimetypes that should be converted.
80 static struct MimeTypeList mimeTypeList[] = {
81 // Mp3 mime types
82 {MIMETYPE_AUDIO, "mp3", sizeof("mp3")-1, mime_type_audio_mpeg},
83 {MIMETYPE_AUDIO, "x-mpeg", sizeof("x-mpeg")-1, mime_type_audio_mpeg},
84 {MIMETYPE_AUDIO, "x-mp3", sizeof("x-mp3")-1, mime_type_audio_mpeg},
85 {MIMETYPE_AUDIO, "mpg", sizeof("mpg")-1, mime_type_audio_mpeg},
86 {MIMETYPE_AUDIO, "mpg3", sizeof("mpg")-1, mime_type_audio_mpeg},
87 {MIMETYPE_AUDIO, "x-mpg", sizeof("x-mpg")-1, mime_type_audio_mpeg},
88 {MIMETYPE_AUDIO, "x-mpegaudio", sizeof("x-mpegaudio")-1, mime_type_audio_mpeg},
89
90 // 3gpp audio mime types
91 {MIMETYPE_AUDIO, "3gp", sizeof("3gp")-1, mime_type_audio_3gpp},
92
93 // Amr audio mime types
94 {MIMETYPE_AUDIO, "amr", sizeof("amr")-1, mime_type_audio_amr},
95
96 // Aac audio mime types
97 {MIMETYPE_AUDIO, "aac", sizeof("aac")-1, mime_type_audio_aac},
98
99 // Wav audio mime types
100 {MIMETYPE_AUDIO, "x-wav", sizeof("x-wav")-1, mime_type_audio_wav},
101
102 // Mpeg4 video mime types
103 {MIMETYPE_VIDEO, "mpg4", sizeof("mpg4")-1, mime_type_video_mpeg4},
104 {MIMETYPE_VIDEO, "mp4v-es", sizeof("mp4v-es")-1, mime_type_video_mpeg4},
105
106 // 3gpp video mime types
107 {MIMETYPE_VIDEO, "3gp", sizeof("3gp")-1, mime_type_video_3gpp},
108
109 // Must be last entry
110 {MIMETYPE_LAST, NULL, 0, NULL}
111 };
112
113 /**
114 * May convert the mimetype if there is a well known
115 * replacement mimetype otherwise the original mimetype
116 * is returned.
117 *
118 * If the mimetype is of unsupported group i.e. application/...
119 * then "unsupported/drm.mimetype" will be returned.
120 *
121 * @param mimeType - mimetype in lower case to convert.
122 *
123 * @return mimetype or "unsupported/drm.mimetype".
124 */
convertMimeType(String8 & mimeType)125 String8 MimeTypeUtil::convertMimeType(String8& mimeType) {
126 String8 result = mimeType;
127 const char* pMimeType;
128 struct MimeGroup* pGroup;
129 struct MimeTypeList* pMimeItem;
130 int len;
131 pMimeType = mimeType.string();
132 if (NULL != pMimeType) {
133 if ((0 == strncmp(pMimeType, mime_group_audio, (sizeof mime_group_audio) - 1)) ||
134 (0 == strncmp(pMimeType, mime_group_video, (sizeof mime_group_video) - 1))) {
135 /* Check which group the mimetype is */
136 pGroup = mimeGroup;
137 while (MIMETYPE_LAST != pGroup->type) {
138 if (0 == strncmp(pMimeType, pGroup->pGroup, pGroup->size)) {
139 break;
140 }
141 pGroup++;
142 }
143
144 /* Go through the mimetype list. Only check items of the correct group */
145 if (MIMETYPE_LAST != pGroup->type) {
146 pMimeItem = mimeTypeList;
147 len = strlen (pMimeType+pGroup->size);
148 while (MIMETYPE_LAST != pMimeItem->type) {
149 if ((pGroup->type == pMimeItem->type) &&
150 (len == pMimeItem->size) &&
151 (0 == strcmp(pMimeType+pGroup->size, pMimeItem->pMimeExt))) {
152 result = String8(pMimeItem->pMimeType);
153 break;
154 }
155 pMimeItem++;
156 }
157 }
158 } else {
159 result = String8(mime_type_unsupported);
160 }
161 LOG_DEBUG("convertMimeType got mimetype %s, converted into mimetype %s",
162 pMimeType, result.string());
163 }
164 return result;
165 }
166 };
167