1 /*
2  * Copyright (c) 2023-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 "mime_type_mgr.h"
17 
18 #include <memory>
19 
20 #include "app_log_wrapper.h"
21 #include "bundle_constants.h"
22 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
23 #include "type_descriptor.h"
24 #include "utd_client.h"
25 #endif
26 
27 namespace OHOS {
28 namespace AppExecFwk {
29 namespace {
30 const char* ZIP_FORMAT = ".zip.";
31 const char* ZIP_SUFFIX = ".zip";
32 const char* FILE_7Z_FORMAT = ".7z.";
33 const char* FILE_7Z_SUFFIX = ".7z";
34 }
35 
GetMimeTypeByUri(const std::string & uri,std::vector<std::string> & mimeTypes)36 bool MimeTypeMgr::GetMimeTypeByUri(const std::string &uri, std::vector<std::string> &mimeTypes)
37 {
38 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
39     std::vector<std::string> utdVector;
40     if (!GetUtdVectorByUri(uri, utdVector)) {
41         APP_LOGD("Get utd vector by uri %{private}s failed", uri.c_str());
42         return false;
43     }
44     for (const std::string &utd : utdVector) {
45         std::shared_ptr<UDMF::TypeDescriptor> typeDescriptor;
46         auto ret = UDMF::UtdClient::GetInstance().GetTypeDescriptor(utd, typeDescriptor);
47         if (ret != ERR_OK || typeDescriptor == nullptr) {
48             APP_LOGE("GetTypeDescriptor failed");
49             continue;
50         }
51         std::vector<std::string> tmpMimeTypes = typeDescriptor->GetMimeTypes();
52         if (tmpMimeTypes.empty()) {
53             APP_LOGD("tmpMimeTypes empty");
54             continue;
55         }
56         mimeTypes.insert(mimeTypes.end(), tmpMimeTypes.begin(), tmpMimeTypes.end());
57     }
58     return !mimeTypes.empty();
59 #else
60     return false;
61 #endif
62 }
63 
GetMimeTypeByUri(const std::string & uri,std::string & mimeType)64 bool MimeTypeMgr::GetMimeTypeByUri(const std::string &uri, std::string &mimeType)
65 {
66     std::vector<std::string> mimeTypes;
67     bool ret = GetMimeTypeByUri(uri, mimeTypes);
68     if (!ret) {
69         return false;
70     }
71     mimeType = mimeTypes[0];
72     return true;
73 }
74 
GetUriSuffix(const std::string & uri,std::string & suffix)75 bool MimeTypeMgr::GetUriSuffix(const std::string &uri, std::string &suffix)
76 {
77     if (uri.find(ZIP_FORMAT) != std::string::npos) {
78         suffix = ZIP_SUFFIX;
79         return true;
80     }
81     if (uri.find(FILE_7Z_FORMAT) != std::string::npos) {
82         suffix = FILE_7Z_SUFFIX;
83         return true;
84     }
85     auto suffixIndex = uri.rfind('.');
86     if (suffixIndex == std::string::npos) {
87         APP_LOGD("Get suffix failed %{private}s", uri.c_str());
88         return false;
89     }
90     suffix = uri.substr(suffixIndex);
91     std::transform(suffix.begin(), suffix.end(), suffix.begin(),
92                 [](unsigned char c) { return std::tolower(c); });
93     return true;
94 }
95 
GetUtdVectorByUri(const std::string & uri,std::vector<std::string> & utdVector)96 bool MimeTypeMgr::GetUtdVectorByUri(const std::string &uri, std::vector<std::string> &utdVector)
97 {
98 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
99     std::string suffix;
100     if (!GetUriSuffix(uri, suffix)) {
101         APP_LOGD("Get suffix failed %{private}s", uri.c_str());
102         return false;
103     }
104     auto ret = UDMF::UtdClient::GetInstance().GetUniformDataTypesByFilenameExtension(suffix, utdVector);
105     if (ret != ERR_OK || utdVector.empty()) {
106         APP_LOGD("Get utd vector by suffix %{public}s failed. err %{public}d", suffix.c_str(), ret);
107         return false;
108     }
109     return true;
110 #else
111     return false;
112 #endif
113 }
114 }
115 }