MimeTypeUtil.cpp revision 90855078eb989944bca1824058d7231cd68e5021
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
20namespace 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(...) LOGD(__VA_ARGS__)
28#else
29#define LOG_DEBUG(...)
30#endif
31
32enum {
33    MIMETYPE_AUDIO       = 0,
34    MIMETYPE_APPLICATION = 1,
35    MIMETYPE_IMAGE       = 2,
36    MIMETYPE_VIDEO       = 3,
37    MIMETYPE_LAST        = -1,
38};
39
40struct 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
46struct 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
55static const char mime_type_audio_mpeg[]  = "audio/mpeg";
56static const char mime_type_audio_3gpp[]  = "audio/3gpp";
57static const char mime_type_audio_amr[]   = "audio/amr-wb";
58static const char mime_type_audio_aac[]   = "audio/mp4a-latm";
59static const char mime_type_audio_wav[]   = "audio/wav";
60
61static const char mime_type_video_mpeg4[] = "video/mpeg4";
62static const char mime_type_video_3gpp[]  = "video/3gpp";
63
64// Known mimetype groups
65static const char mime_group_audio[]       = "audio/";
66static const char mime_group_application[] = "application/";
67static const char mime_group_image[]       = "image/";
68static const char mime_group_video[]       = "video/";
69static const char mime_type_unsupported[]  = "unsupported/drm.mimetype";
70
71static 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.
80static 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 */
125String8 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