1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ringtone_mimetype_utils.h"
17
18 #include <fstream>
19
20 #include "ringtone_log.h"
21 #include "ringtone_errno.h"
22
23 namespace OHOS {
24 namespace Media {
25 using namespace std;
26 using namespace nlohmann;
27
28 using MimeTypeMap = unordered_map<string, vector<string>>;
29
30 MimeTypeMap RingtoneMimeTypeUtils::mediaJsonMap_;
31 const string MIMETYPE_JSON_PATH = "/system/etc/userfilemanager/userfilemanager_mimetypes.json";
32 const string DEFAULT_MIME_TYPE = "application/octet-stream";
33
34 /**
35 * The format of the target json file:
36 * First floor: Media type string, such as image, video, audio, etc.
37 * Second floor: Mime type string
38 * Third floor: Extension array.
39 */
CreateMapFromJson()40 void RingtoneMimeTypeUtils::CreateMapFromJson()
41 {
42 std::ifstream jFile(MIMETYPE_JSON_PATH);
43 if (!jFile.is_open()) {
44 RINGTONE_ERR_LOG("Failed to open: %{private}s", MIMETYPE_JSON_PATH.c_str());
45 return;
46 }
47 json firstFloorObjs;
48 jFile >> firstFloorObjs;
49 for (auto& firstFloorObj : firstFloorObjs.items()) {
50 json secondFloorJsons = json::parse(firstFloorObj.value().dump(), nullptr, false);
51 if (secondFloorJsons.is_discarded()) {
52 continue;
53 }
54 for (auto &secondFloorJson : secondFloorJsons.items()) {
55 json thirdFloorJsons = json::parse(secondFloorJson.value().dump(), nullptr, false);
56 // Key: MimeType, Value: Extension array.
57 if (!thirdFloorJsons.is_discarded()) {
58 mediaJsonMap_.insert(std::pair<string, vector<string>>(secondFloorJson.key(), thirdFloorJsons));
59 }
60 }
61 }
62 }
63
InitMimeTypeMap()64 int32_t RingtoneMimeTypeUtils::InitMimeTypeMap()
65 {
66 CreateMapFromJson();
67 if (mediaJsonMap_.empty()) {
68 RINGTONE_ERR_LOG("JsonMap is empty");
69 return E_FAIL;
70 }
71 return E_OK;
72 }
73
GetMimeTypeFromExtension(const string & extension)74 string RingtoneMimeTypeUtils::GetMimeTypeFromExtension(const string &extension)
75 {
76 return GetMimeTypeFromExtension(extension, mediaJsonMap_);
77 }
78
GetMimeTypeFromExtension(const string & extension,const MimeTypeMap & mimeTypeMap)79 string RingtoneMimeTypeUtils::GetMimeTypeFromExtension(const string &extension,
80 const MimeTypeMap &mimeTypeMap)
81 {
82 string tmp = extension;
83 transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
84 for (auto &item : mimeTypeMap) {
85 for (auto &ext : item.second) {
86 if (ext == tmp) {
87 return item.first;
88 }
89 }
90 }
91 return DEFAULT_MIME_TYPE;
92 }
93
GetMediaTypeFromMimeType(const string & mimeType)94 RingtoneMediaType RingtoneMimeTypeUtils::GetMediaTypeFromMimeType(const string &mimeType)
95 {
96 size_t pos = mimeType.find_first_of("/");
97 if (pos == string::npos) {
98 RINGTONE_ERR_LOG("Invalid mime type: %{public}s", mimeType.c_str());
99 return RINGTONE_MEDIA_TYPE_INVALID;
100 }
101 string prefix = mimeType.substr(0, pos);
102 if (prefix == "audio") {
103 return RINGTONE_MEDIA_TYPE_AUDIO;
104 } else {
105 RINGTONE_ERR_LOG("Invalid mime type: %{public}s", mimeType.c_str());
106 return RINGTONE_MEDIA_TYPE_INVALID;
107 }
108 }
109 } // namespace Media
110 } // namespace OHOS
111